首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Errno::ENOMEM:无法分配内存- cat

Errno::ENOMEM:无法分配内存- cat
EN

Stack Overflow用户
提问于 2013-02-26 10:01:15
回答 3查看 36.5K关注 0票数 16

我有一个在生产中运行的作业,它处理xml文件。xml文件的数量大约为4k,大小为8至9GB。

经过处理,得到CSV文件作为输出。我有一个cat命令,它将把所有CSV文件合并到一个文件中:

Errno::ENOMEM:无法分配内存

cat (回拨)命令上。

以下是一些细节:

  • 系统内存-4GB
  • 交换-2GB
  • Ruby : 1.9.3p286

文件使用nokogirisaxbuilder-0.0.8进行处理。

这里有一个代码块,它将处理4000个XML文件,并将输出保存在CSV中(每个xml 1)(对不起,我不打算共享它,因为这是公司策略的一部分)。

下面是将输出文件合并为单个文件的代码

代码语言:javascript
复制
Dir["#{processing_directory}/*.csv"].sort_by {|file| [file.count("/"), file]}.each {|file|
            `cat #{file} >> #{final_output_file}`
}

我在processing.It期间使用了内存消耗快照,几乎消耗了内存的所有部分,但是,它不会失败。它总是在cat命令上失败。

我猜,在回击时,它试图生成一个没有足够内存的新进程,因此失败了。

请让我知道你的意见和替代这一点。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-26 14:35:24

因此,您的系统内存似乎很低,生成一个shell +调用cat对于剩下的几个内存来说太大了。

如果你不介意失去一些速度,你可以合并在红宝石文件,与小缓冲区。这样可以避免生成shell,并且可以控制缓冲区大小。

这是未经检验的,但你有这样的想法:

代码语言:javascript
复制
buffer_size = 4096
output_file = File.open(final_output_file, 'w')

Dir["#{processing_directory}/*.csv"].sort_by {|file| [file.count("/"), file]}.each do |file|
  f = File.open(file)
  while buffer = f.read(buffer_size)
    output_file.write(buffer)
  end
  f.close
end
票数 3
EN

Stack Overflow用户

发布于 2016-07-10 02:53:03

您可能没有物理内存,所以请再次检查并验证您的交换(free -m)。如果您没有交换空间,创造一个

否则,如果您的内存很好,则该错误很可能是由shell资源限制引起的。您可以通过ulimit -a检查它们。

它们可以由ulimit修改,它可以修改shell资源限制(参见:help ulimit)。

代码语言:javascript
复制
ulimit -Sn unlimited && ulimit -Sl unlimited

要使这些限制持久,您可以通过以下shell命令创建ulimit设置文件来配置它:

代码语言:javascript
复制
cat | sudo tee /etc/security/limits.d/01-${USER}.conf <<EOF
${USER} soft core unlimited
${USER} soft fsize unlimited
${USER} soft nofile 4096
${USER} soft nproc 30654
EOF

或者使用/etc/sysctl.conf来改变全局限制(man sysctl.conf)。

代码语言:javascript
复制
kern.maxprocperuid=1000
kern.maxproc=2000
kern.maxfilesperproc=20000
kern.maxfiles=50000
票数 3
EN

Stack Overflow用户

发布于 2015-04-04 08:49:11

我也有同样的问题,但不是cat,而是sendmail (gem mail)。

我通过安装这里 gem找到了问题和解决方案posix-spawn

代码语言:javascript
复制
gem install posix-spawn

下面是一个例子:

代码语言:javascript
复制
a = (1..500_000_000).to_a

require 'posix/spawn'
POSIX::Spawn::spawn('ls')

这一次,创建子进程应该成功。

另见:甲骨文的最小化创建应用程序子进程的内存使用量

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15086133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档