我有一个ruby脚本,在内存中加载了大量的数据,然后需要提取出来执行这个数据的任务。 但有时候,数据太大,脚本在交换中运行,在这种情况下,脱壳会给我一个Errno::ENOMEM
错误。
这里是重现问题的脚本:
def current_process_ram pid, size = `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i) size / 1000 end def display_current_process_ram "Current RAM: #{current_process_ram}" end puts display_current_process_ram array = [] one_gig = 14_000_000 0.upto(one_gig * 2.5) do array << '12345' end sleep 2 `ls` puts display_current_process_ram
htop
: htop
: deploy@vagrant-ubuntu-trusty-64:~/statusmachine$ ruby test.rb Current RAM: 7 test.rb:19:in ``': Cannot allocate memory - ls (Errno::ENOMEM) from test.rb:19:in `<main>'
它运行在Ubuntu服务器“可信赖的tahr”虚拟机上。
为什么我会收到Errno::ENOMEM
错误? 我希望系统调用工作,因为我有足够的交换来执行它。
编辑:如果我改变脚本只使用1演出,炮击时不爆炸。
编辑2:当我掏出,还有很多交换来执行系统调用,所以不应该有Errno::ENOMEM
发生。
编辑3:澄清我的问题。
为什么我会收到Errno :: ENOMEM错误?
因为Ruby不能分配足够的内存。
当你使用典型的Ruby,也就是KRI,MRI,YARV时,Ruby的内存管理是困难的(恕我直言)。
这里有一篇文章可以帮助你:
http://adamniedzielski.github.io/blog/2014/02/05/fighting-paperclip-errno-enomem-error/
文章中的主要思想是:“要创建子进程,空闲内存必须大于父进程占用的内存”。
文章中的解决方案是切换到使用posix-spawn
宝石: