【发布时间】:2014-01-13 00:20:46
【问题描述】:
我有一个 ruby 脚本,仅包含一个哈希表,它是由另一个脚本通过使用 PP.pp(mediacontent,filehandle) 将其转储到文件中编写的。
生成此哈希表的脚本通过逐页从供应商下载数据、解析 XML 并将所需对象转换为此哈希表来生成此哈希表,该哈希表会随着脚本下载更多数据而增长。
转储看起来像这样,前 2 1/2 个对象显示:
文件:mediacontent.rb
# encoding: utf-8
$mediacontent =
{"099923045533"=>
{"obj"=>
{"external_id"=>"099923045533",
"media_type_id"=>5,
"active"=>true,
"name"=>"F.D.B.",
"duration"=>286,
"published_at"=>"2013-05-29T20:05:11Z",
"properties"=>
{"host"=>"Vevo",
"host_url"=> "http://example.com/sample.m3u8",
"favorites"=>"0",
"views"=>"8495",
"trending"=>"298",
"popular"=>"1401",
"copyright"=>"2013 Hustle Gang/Grand Hustle/eOne Music",
"src_img_path"=>"http://example.com/xyz.jpg",
"src_img_dim"=>"1241x697"}},
"data"=>{}},
"AEA040800053"=>
{"obj"=>
{"external_id"=>"AEA040800053",
"media_type_id"=>5,
"active"=>true,
"name"=>"Aadi",
"duration"=>351,
"published_at"=>"2009-10-02T00:00:00Z",
"properties"=>
{"host"=>"Vevo",
"host_url"=>"http://example.com/sample2.m3u8",
"favorites"=>"1",
"views"=>"20160",
"trending"=>"0",
"popular"=>"0",
"copyright"=>"EMI Music Arabia",
"src_img_path"=>"http://example.com/sample2.jpg",
"src_img_dim"=>"640x339"}},
"data"=>{}},
"AEAB20400094"=>
{"obj"=>
{"external_id"=>"AEAB20400094",
"media_type_id"=>5,
etc.
},
"data"=>{}},
etc...
}
包含其他哈希的相当标准的 ruby 哈希。
此列表中有 75,000 个主键。
当我尝试执行以下操作时:
ruby mediacontent.rb
或在脚本中
require "./mediacontent.rb"
我得到了错误
mediacontent.rb:0: stack level too deep (SystemStackError)
如果我从该表中删除大约 30,000 个条目,该错误就会消失。我已经验证没有无休止的嵌套。每个主键都是一个包含嵌套哈希“obj”、“properties”和“data”的哈希。就是这样。
我觉得奇怪的是,生成这个表的脚本在将它转储出来之前在内部构建这个大哈希表没有问题。如果脚本的执行被中断并且必须重新运行,则该脚本应该(通过要求)将其读回。在哈希表增长到 75,000 个项目之前,这也能正常工作。
我正在运行 ruby 1.9.3p484。没有导轨。只是红宝石。
【问题讨论】:
-
@JustinWood - 第二个链接不会转到页面上的任何锚点。如果您谈论的是 size 属性,那么如果 Ruby 甚至拒绝加载散列,就不可能调用它。看来我已经遇到了对象大小的最大限制。源文件大约 52 兆字节。如果我将它分成 2 个单独的哈希表,它们加载得很好。如果是大小限制,那么 Ruby 错误消息“堆栈级别太深”就不太适合显示了。
-
我这里有很深的递归,你自己写脚本吗?
-
@majioa - 我自己编写了脚本,没有任何递归。该脚本非常基本:下载一个 XML 文件,解析它,将数据对象保存在哈希表中,然后重复。每 1000 个对象,将哈希表保存到一个单独的 Ruby 源文件。如果脚本被中断,它会在下次运行时需要包含散列的源文件,并从中断处继续。在哈希表超过一定大小之前,这种方法运行良好。这似乎是 Ruby 的一个错误(或功能?),它要么限制哈希表的大小,要么限制源文件的大小,不确定是哪个。
-
好的,尝试使用
ulimit将堆栈大小增加两次,例如增加到 16384 kbytes 为:ulimit -s 16384。
标签: ruby hash hashtable stack-overflow