为Rails获取错误“无法分配内存”
在我的项目中,有一个脚本返回我必须在表中显示的产品列表。
要存储我使用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
我该怎么办?
IO.popen
和Kernel#system
在内存方面都是昂贵的操作,因为它们都依赖于fork(2)。 Fork(2)是一个Unix系统调用,它创建一个子进程来克隆父进程的内存和资源。 这意味着,如果您的父进程使用500mb的内存,那么您的孩子也将使用500mb的内存。 每次执行Kernel#system
或IO.popen
都会增加应用程序的内存使用量,以减少运行Rails应用程序所需的内存量。
如果您的开发机器具有比生产服务器更多的RAM,或者您的生产服务器产生更多输出,那么您可以做两件事:
- 增加生产服务器的内存。
- 使用Resque之类的东西做一些内存管理。
您可以使用Resque将这些操作排入作业。 然后,Resque将生成“workers”/子进程以从队列中获取作业,对其进行处理然后退出。 Resque仍然分叉,但重要的是工作人员在完成任务后退出以释放内存。 每次工作人员完成工作时,内存都会出现峰值,但每次工作后都会返回到应用程序的基线内存。
您可能必须执行上述两个选项,并寻找其他方法来最小化应用程序的内存使用量。
看来device list
的输出太大了。
“ 无法分配内存(Errno :: ENOMEM) ”是描述问题的有用链接。
限制device list
的输出并检查。 然后你就可以知道它是否是一个内存问题。