Errno :: ENOMEM当使用交换进程shell时

我有一个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宝石:

https://github.com/rtomayko/posix-spawn