Ruby:无法分配内存

Nodari Lipartiya

我正在开发Ruby on Rails应用程序。我是Ruby / Rails的新手。我使用Ruby 2.2.0和Rails 4.2。当我运行类似的命令时:

rails g migration SomeMigrationName

它失败了

Cannot allocate memory - fork(2) (Errno::ENOMEM)

我将Macbook Pro与OS X 10.10一起安装在主板上,并使用Vagrant / Virtualbox来运行用于Rails开发的虚拟机(Ubuntu 14.04)。

这是我的Vagrant文​​件:

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.network "forwarded_port", guest: 3000, host: 3000
  config.vm.synced_folder "dev", "/home/vagrant/dev"
  config.vm.synced_folder "opt", "/opt"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "512"
  end
end

我已经读到,当RAM超出限制时会发生这样的错误,但是我对另一个运行多个Python / Tornado应用程序,MongoDB和Redis的开发环境使用相同的配置(流浪文件),并且一切正常。

我是否需要增加vb.memory的值,或者这是一个Ruby错误?

马特

当Ruby调用时fork,即使只将fork调用到exec另一个小进程(如),OS也会复制整个父进程的地址空间ls暂时,您的系统需要能够分配至少一块Ruby父进程大小的内存,然后再将其分解为子进程的实际需求。

因此,Rails通常非常消耗内存。然后,如果使用fork,则需要两倍的内存。

TL; DR如果可以控制代码,请使用posix-spawn而不是fork。否则,给您的VM 1024MB或一点额外的交换空间,以占用fork通话的余量


Ruby内存使用示例fork

随机抽取一个虚拟机,该虚拟机已禁用交换空间:

$ free -m
             total       used       free     shared    buffers     cached
Mem:          1009        571        438          0          1         35
-/+ buffers/cache:        534        475
Swap:            0          0          0

查看Mem:行和free列。这大约是您对新流程的大小限制,在我的情况下为438MiB

buffers/cached已经为此测试刷新,以至于我的free记忆力已达到极限。如果buffers/cache值较大,则可能需要考虑这些值。当进程需要内存时,Linux可以清除过时的缓存。


耗尽一些内存

创建一个红宝石进程,并使用一个与可用内存大小相近的字符串。ruby过程有一些开销,因此不会完全匹配free

$ ruby -e 'mb = 380; a="z"*mb*2**20; puts "=)"'
=)


然后将字符串稍大一些:

$ ruby -e 'mb = 385; a="z"*mb*2**20; puts "=)"'
-e:1:in `*': failed to allocate memory (NoMemoryError)
        from -e:1:in `<main>'


fork在红宝石过程中添加一个mb直到运行为止。

$ ruby -e 'mb = 195; a="z"*mb*2**20; fork; puts "=)"'
=)


稍大的fork过程将产生ENOMEM错误:

$ ruby -e 'mb = 200; a="z"*mb*2**20; fork; puts "=)"'
-e:1:in `fork': Cannot allocate memory - fork(2) (Errno::ENOMEM)
        from -e:1:in `<main>'


运行带有反引号的命令会以forkso启动该过程,其结果相同:

$ ruby -e 'mb = 200; a="z"*mb*2**20; `ls`'
-e:1:in ``': Cannot allocate memory - ls (Errno::ENOMEM)
        from -e:1:in `<main>'


因此,您需要大约两倍于系统上可用的父进程内存来派生新进程。MRI Rubyfork的多进程模型非常依赖,这是因为Ruby的设计使用了全局解释器锁(GIL)全局解释器锁在每个ruby进程中一次只能执行一个线程。

我相信Python在fork内部使用的很少当您os.fork在Python中使用时,会发生以下情况:

python -c 'a="c"*420*2**20;'
python -c 'import os; a="c"*200*2**20; os.fork()'


Oracle关于此问题详细的文章,并讨论了使用.NET的替代方法posix_spawn()本文针对Solaris,但这是POSIX Unix的一般性问题,因此适用于Linux(如果不是大多数Unices)。

posix-spawn如果您可以控制代码,也可以使用Ruby实现该模块不会替换Rails中的任何内容,因此除非您替换了对fork自己的调用,否则它对您没有帮助

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

无法在Ruby中分配内存(无MemoryError)?

来自分类Dev

无法在Ruby中分配内存(无MemoryError)?

来自分类Dev

mmap:无法分配内存

来自分类Dev

无法分配内存

来自分类Dev

无法捕获内存分配失败

来自分类Dev

git fetch:无法分配内存

来自分类Dev

XZ-无法分配内存

来自分类Dev

无法启动插孔(无法分配内存)

来自分类Dev

Ruby gsub,NoMemoryError:分配内存失败。

来自分类Dev

内存不足,无法在PHP中分配

来自分类Dev

为什么mmap无法分配内存?

来自分类Dev

Python MemoryError:无法分配数组内存

来自分类Dev

R:无法分配大于x MB的内存

来自分类Dev

JavaFx MediaPlayer-无法分配内存或OutOfMemory

来自分类Dev

无法更改分配给AVD的内存

来自分类Dev

无法确定分配内存的正确算法

来自分类Dev

从SCSI磁带读取时,“无法分配内存”

来自分类Dev

realloc()无法重新分配内存

来自分类Dev

JavaFx MediaPlayer-无法分配内存或OutOfMemory

来自分类Dev

隐藏错误,无法为池分配内存

来自分类Dev

Malloc无法为结构分配内存

来自分类Dev

尝试“ yum -y更新”无法分配内存

来自分类Dev

Spark提交错误“无法分配内存”

来自分类Dev

无法在分配的内存中执行查询

来自分类Dev

无法在 Python 中使用 tshark 分配内存

来自分类Dev

无法分配大量虚拟内存

来自分类Dev

即使有可用内存,系统也无法分配内存

来自分类Dev

Eclipse ADT:无法创建密钥,无法分配内存

来自分类Dev

分配内存