为Rails获取错误“无法分配内存”

时间:2013-12-03 16:48:11

标签: ruby-on-rails ruby ruby-1.8

在我的项目中,有一个脚本返回我必须在表格中显示的产品列表。

要存储我使用的脚本IO.popen

的输入
@device_list = []
IO.popen("device list").each do |device|
  @device_list << device
end

device list是给我产品列表的命令。

我通过迭代将@device_list数组返回到我的视图中进行显示。

当我运行它时出现错误:

Errno::ENOMEM (Cannot allocate memory):
for IO.popen

我有另一个脚本device status只返回true和false但是我得到了同样的错误:

def check_status(device_id)        
    @stat = system("status device_id")
    if @stat == true
         "sold"
    else
         "not sold"
    end
  end

我该怎么办?

2 个答案:

答案 0 :(得分:14)

IO.popenKernel#system在内存方面都可能是昂贵的操作,因为它们都依赖于fork(2)。 Fork(2)是一个Unix系统调用,它创建一个子进程来克隆父进程的内存和资源。这意味着,如果您的父进程使用500mb的内存,那么您的孩子也将使用500mb的内存。每次执行Kernel#systemIO.popen时,都会增加应用程序的内存使用量,以减少运行Rails应用程序所需的内存量。

如果你的开发机器有比生产服务器更多的RAM,或者你的生产服务器产生了更多的输出,你可以做两件事:

  1. 增加生产服务器的内存。
  2. 使用Resque等内容进行内存管理。
  3. 您可以使用Resque将这些操作排入作业。然后,Resque将生成&#34; workers&#34; /子进程以从队列中获取作业,对其进行处理然后退出。 Resque仍然分叉,但重要的是工作人员在完成任务后退出以释放内存。每次工作人员完成工作时,内存都会出现峰值,但每次工作后都会回到应用程序的基线内存中。

    您可能必须同时执行上述两个选项,并寻找其他方法来最小化应用的内存使用量。

答案 1 :(得分:0)

device list的输出似乎太大了。

Cannot allocate memory (Errno::ENOMEM)”是描述问题的有用链接。

限制device list的输出并检查。然后你就可以知道它是否是一个内存问题。