ruby - 使用交换时进程退出时出现 Errno::ENOMEM

标签 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 服务器“trusty tahr”虚拟机上运行。

我的问题

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


编辑:如果我将脚本更改为仅使用 1 gig,则在炮弹发射时它不会爆炸。

编辑2:当我退出时,仍然有大量交换来执行系统调用,因此不应该发生 Errno::ENOMEM

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

最佳答案

Why do I get the Errno::ENOMEM error?

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

当您使用典型的 Ruby(又名 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

关于ruby - 使用交换时进程退出时出现 Errno::ENOMEM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30219106/

相关文章:

php - PHP 中的 MP3 和 OGG 标签

Linux 和 I/O 完成端口?

javascript - 使用 AJAX 在 Rails 中更新动态 ChartJS 图表

ruby-on-rails - 即使安装了 libv8,Gem therubyracer 也不会安装

linux - 实时随机静音部分输入音频

perl - 从 shell 调用系统调用的通用方法

python - 通过 shell 脚本调用 python 脚本时出现 ImportError

bash - 提取子字符串直到第一个数字

ruby-on-rails - 是否可以将正则表达式传递给 'rspec` 命令行命令?

ruby-on-rails - 在 Rails View 中创建拖放表的更好方法是什么?