Errno :: ENOMEM在使用swap时处理shell

时间:2015-05-13 15:21:15

标签: ruby linux shell memory

我有一个ruby脚本,它在内存中加载了大量数据,然后需要shell出来对这些数据执行任务。但有时,数据太大以至于脚本在交换中运行,在这种情况下,shelling out会给我一个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

before running script

脚本运行时

htop

while script is running

产生的错误:

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服务器上运行&#34; trusty tahr&#34; VM。

我的问题

为什么我会收到Errno::ENOMEM错误?我希望系统调用能够工作,因为我有足够的交换来执行它。

编辑:如果我将剧本更改为仅使用1演出,则在炮击时不会爆炸。

编辑2:当我退出时,仍然有很多交换来执行系统调用,所以不应该发生Errno::ENOMEM

编辑3:澄清了我的问题。

1 个答案:

答案 0 :(得分:3)

  

为什么我会收到Errno :: ENOMEM错误?

因为Ruby无法分配足够的内存。

当您使用典型的Ruby,a.k.a.KRI,MRI,YARV时,Ruby的内存管理很难(恕我直言)关于炮击。

这篇文章可以帮助您:

http://adamniedzielski.github.io/blog/2014/02/05/fighting-paperclip-errno-enomem-error/

本文中的关键思想是:“要创建子进程,可用内存必须大于父进程占用的内存。”

本文中的解决方案是切换到使用posix-spawn gem:

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