【发布时间】:2018-08-15 15:36:30
【问题描述】:
我生成了一个在其他场合对我有用的简单脚本,但这是因为循环中的信息量会产生 NoMemoryError 错误。
我有 16 GB 的内存和大量可用的虚拟内存。当我执行测试时,RAM 内存已完全填满。
脚本是:
require 'rest-client'
require 'json'
require 'open-uri'
require 'csv'
def self.qos7705egressdiscard_summary
xml = File.read("#{Rails.root}/public/Discard_qos7705egress.xml")
data = RestClient.post("http://10.140.255.1:8080/xmlapi/invoke", xml,{:"Content-Type" => 'application/soap+xml'})
data_parsed = Hash.from_xml(data)
return data_parsed
end
def self.samqos7705egressdiscardtotal_table
tabletotal = Hash.new
data_stats = qos7705egressdiscard_summary['Envelope']['Body']['findResponse']['result']['service.SapEgrQosQueueStatsLogRecord']
data_stats.map do |qosdiscard_device|
@devicetotal = qosdiscard_device["monitoredObjectSiteName"]
@servicetotal = qosdiscard_device["monitoredObjectPointer"]
@porttotal = qosdiscard_device["displayedName"]
@queueIdtotal = qosdiscard_device["queueId"]
@discardinproftotal = qosdiscard_device["droppedInProfOctets"].to_i
@discardoutproftotal = qosdiscard_device["droppedOutProfOctets"].to_i
time_unixtotal = (qosdiscard_device["timeCaptured"]).to_i/1000
@timeCapturedtotal = Time.at(time_unixtotal).strftime("%B %e, %Y at %I:%M %p")
@discardtotal = @discardinproftotal + @discardoutproftotal
@device_int_stats_total = (@devicetotal+@porttotal+@queueIdtotal).to_s
hash = Hash[devicetotal: @devicetotal, servicetotal: @servicetotal, porttotal: @porttotal, queueIdtotal: @queueIdtotal, discardtotal: @discardtotal, device_int_stats_total: @device_int_stats_total, timeCapturedtotal: @timeCapturedtotal, time_unixtotal: time_unixtotal]
tabletotal << hash
#tabletotal.write(hash)
end
end
确切的错误是:
NoMemoryError: failed to allocate memory
from /usr/local/lib/ruby/2.2.0/irb/inspector.rb:108:in `inspect'
from /usr/local/lib/ruby/2.2.0/irb/inspector.rb:108:in `block in <module:IRB>'
from /usr/local/lib/ruby/2.2.0/irb/inspector.rb:101:in `call'
from /usr/local/lib/ruby/2.2.0/irb/inspector.rb:101:in `inspect_value'
from /usr/local/lib/ruby/2.2.0/irb/context.rb:383:in `inspect_last_value'
from /usr/local/lib/ruby/2.2.0/irb.rb:661:in `output_value'
from /usr/local/lib/ruby/2.2.0/irb.rb:490:in `block (2 levels) in eval_input'
from /usr/local/lib/ruby/2.2.0/irb.rb:623:in `signal_status'
from /usr/local/lib/ruby/2.2.0/irb.rb:486:in `block in eval_input'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:245:in `block (2 levels) in each_top_level_statement'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `loop'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `block in each_top_level_statement'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `catch'
from /usr/local/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `each_top_level_statement'
from /usr/local/lib/ruby/2.2.0/irb.rb:485:in `eval_input'
from /usr/local/lib/ruby/2.2.0/irb.rb:395:in `block in start'
from /usr/local/lib/ruby/2.2.0/irb.rb:394:in `catch'
from /usr/local/lib/ruby/2.2.0/irb.rb:394:in `start'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/console.rb:110:in `start'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/console.rb:9:in `start'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:68:in `console'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'Maybe IRB bug!
在第 25 行,我添加了这个 tabletotal.write (hash) 以便能够将其写入磁盘而不是内存,但出现以下错误:
NoMethodError: undefined method `write' for {}:Hash
这里有什么问题?还有怎么解决?
【问题讨论】:
-
错误告诉你 tabletotal 是一个 Hash,当你调用 tabletotal.write 时,你调用的是对 hash 的 write,这会引发错误。你应该把什么叫做“写”?
-
首先让你的代码少一些 sh*tty。您不需要所有这些实例变量 - 只需直接组成散列并将输入值映射到输出即可。此外,您应该更改方法的签名以将输入作为参数,以便您可以以合理的方式对其进行测试。
-
我找到了一个类似我的问题的解决方案,我想应用它。 stackoverflow.com/questions/23520758/…
-
我需要所有这些变量,因为我在表格格式的 html 中使用它们。
-
但它甚至无法工作,因为每次迭代都会覆盖实例变量 - 您需要遍历表中的数组或哈希。现在只关注输入/输出。
标签: ruby-on-rails ruby memory memory-leaks