在我的项目中有一个脚本返回我必须在表格中显示的产品列表。
为了存储脚本的输入,我使用了 IO.popen
:
@device_list = []
IO.popen("device list").each do |device|
@device_list << device
end
device list
是给我产品列表的命令。
我将 @device_list
数组返回到我的 View ,以便通过迭代它来显示。
当我运行它时出现错误:
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 将产生“ worker ”/子进程以从队列中获取作业,处理它然后退出。 Resque 仍然会 fork ,但重要的是 worker 在完成任务后退出,以便释放内存。每次工作人员完成一项工作时,内存都会出现峰值,但每次完成后它都会回到应用程序的基线内存。
您可能必须执行上述两个选项,并寻找其他方法来最大限度地减少应用的内存使用量。
关于ruby-on-rails - 获取 Rails 错误 "Cannot allocate memory",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20356927/