【发布时间】:2015-04-09 21:58:37
【问题描述】:
我和其他几个人现在是一些用 Perl 编写的遗留批处理作业的快乐维护者。大约 30k 行代码,分成 10-15 个 Perl 文件。
我们有很多长期的修复方法来改进批处理的工作方式,但在短期内,我们必须为依赖这些批处理作业输出的各种其他项目保持亮灯。
这些批处理作业的主要部分的核心是一个散列,它加载了从一堆目录中的各种数据文件收集的一堆数据。首次编写这些内容时,所有内容都非常适合内存 - 不超过 100MB 左右。当然,这些年来事情一直在增长,现在哈希值已经增长到盒子可以处理的容量(8GB),给我们留下了来自 Perl 的好消息:
Out of memory!
当然,这对于批处理作业来说是一个糟糕的设计,我们有一个明确的(长期)路线图来改进这个过程。
但是我有两个问题:
- 除了向机器投入更多内存之外,我们还有哪些短期选择?任何可以调整的操作系统设置?可以设置的 Perl 运行时/编译标志?
- 我还想了解为什么 Perl 会因“内存不足!”而崩溃错误,而不是使用机器上可用的交换空间。
作为参考,它在运行 Solaris 10 的 Sun SPARC M3000 上运行,具有 8 个内核、8 GB RAM、10 GB 交换空间。
在机器上投入更多内存并不是真正理想的解决方案的原因主要是因为它运行的硬件。与 x86 世界相比,为这些 Sun 设备购买更多内存是非常昂贵的,而且我们可能不会再保留这些内存超过一年。
长期的解决方案当然是重构大量代码库,并迁移到 x86 上的 Linux。
【问题讨论】:
-
Solaris 上的 32 位版本的 perl 将在 3.7GB 左右出现,无论系统有什么内存。
-
所有关于不啜饮等的一般性建议都适用。但是,请至少显示散列的一般结构。如果您有复杂的数据结构,请查看是否无法将某些数组或 hashrefs 转换为您根据需要扩展的字符串。
-
你可以尝试
tie将哈希值添加到DBM::Deep对象。不过,请务必阅读文档中有关无限循环的警告。 -
值得检查 ulimit 以确保 perl 进程不会被过早限制
标签: perl out-of-memory solaris