所以,你可以做些什么来保持Perl脚本使用更少的内存。我对任何建议感兴趣,无论他们是编写代码的实际提示,或者如何不同地编译Perl的提示。
编辑Bounty:
我有一个perl程序,作为网络应用程序的服务器。每个连接到它的客户端都会得到它自己的子进程。我也使用线程而不是叉,但我还没有能够确定是否使用线程而不是叉是实际上更有效的内存。
我想再次尝试使用线程而不是叉子。我相信理论上应该节省内存使用。我在这方面有几个问题:
>在Perl中创建的线程阻止复制Perl模块库
进入内存的每个线程?
>是threads(使用线程)最有效的方式(或唯一)
方法在Perl中创建线程?
>在线程中,我可以指定一个stack_size参数,具体是什么
我应该考虑什么时候指定这个值,以及它如何影响
内存使用情况?
使用Perl / Linux中的线程,在每个线程的基础上确定实际内存使用情况的最可靠的方法是什么?
解决方法
一般来说,Perl坚持使用任何内存,即使它不使用它。意识到在一个方向上优化,例如。内存,可能对另一个负面影响,如速度。
这不是一个全面的列表(还有Programming Perl更多):
☹使用Perl内存分析工具来帮助您找到问题区域。参见Profiling heap memory usage on perl programs和How to find the amount of physical memory occupied by a hash in Perl?
☹使用最小范围的词法变量,以允许Perl在不需要时重新使用该内存。
☹避免创建大的临时结构。例如,使用foreach读取文件会一次读取所有输入。如果你只需要逐行,使用while。
foreach ( <FILE> ) { ... } # list context,all at once while( <FILE> ) { ... } # scalar context,line by line
☹您可能甚至不需要在内存中的文件。 Memory-map files instead of slurping them
☹如果你需要创建大数据结构,考虑像DBM::Deep或其他存储引擎,以保持大部分的RAM和磁盘上,直到你需要它。
☹不要让人们使用你的程序。每当我这样做,我已经减少了大约100%的内存占用。它还减少了支持请求。
☹通过引用传递大块的文本和大型聚合,所以你不做一个副本,因此存储相同的信息两次。如果你要复制它,因为你想改变一些东西,你可能会被卡住。这两种方式都作为子程序参数和子程序返回值:
call_some_sub( \$big_text,\@long_array ); sub call_some_sub { my( $text_ref,$array_ref ) = @_; ... return \%hash; }
☹跟踪模块中的内存泄漏。我有一个应用程序的大问题,直到我意识到a module wasn’t releasing memory.我发现一个补丁在模块的RT队列,应用它,并解决了这个问题。
☹如果您需要处理大块数据一次,但不想持久性内存占用,将工作卸载到子进程。子进程在工作时只有内存占用。当你得到答案,子进程关闭并释放它的内存。类似地,工作分布系统,例如Gearman,可以在机器之间传播工作。
☹将递归解成为迭代解。 Perl没有尾递归优化,所以每个新的调用添加到调用堆栈。你可以使用goto或一个模块自己优化尾部问题,但这是一个很大的工作挂在你可能不需要的技术。
☹他使用6 Gb还是仅使用了5 Gb?好吧,告诉你的真相,在所有这种兴奋我失去了自己的轨道。但是作为这个Perl,世界上最强大的语言,并会打击你的记忆清除,你必须问自己一个问题:我觉得幸运吗?好吧,你好,朋克?
还有更多,但是它太早在早上弄清楚这些是什么。我在Mastering Perl和Effective Perl Programming涵盖一些。