Perl线程慢慢消耗内存

时间:2010-07-15 02:16:16

标签: multithreading perl performance sockets memory

4 个答案:

答案 0 :(得分:15)

你的Perl已经4岁半了。升级到5.12。只需搜索5.12构建说明,看看它有哪些主要线程改进,可能只是神奇地修复你的模糊问题:

  • 5.12 :: @_和$ _不再在线程下泄漏(RT#34342和#41138,也是#70602,#70974)'
  • 5.10 ::在ithreads下,PL_reg_curpm中的正则表达式现在被引用计数。这消除了许多hackish变通方法,以应对它没有被引用计数。
  • 5.9 :: threads:一些修复,例如join()问题和内存泄漏。在某些使用glibc的平台(如Linux)中,一个ithread的最小内存占用量减少了几百KB。
  • 5.9 :: threads :: shared许多内存泄漏已得到修复。

我的意思是当你谈到四年的开发以及可能导致这个问题的各种各样的事情时,列表就会继续下去,请查看现代更改日志threads::shared

我评论了你的帖子,这将是我的下一组建议:如果你没有使用glibc而你正在使用perl malloc(默认),你将永远不会向操作系统释放内存。进程大小将代表perl每个占用的最大大小。尝试使用glibc malloc进行重建(需要重新编译),看看是否提供了不同的内存配置文件。除此之外,是时候展示代码了。

答案 1 :(得分:6)

最后钉了泄漏。首先,我想向您展示改进。您不应该查看实际数字,因为自第一张图表以来用户群已经增加,只需查看斜率的差异。

之前的内存使用情况图:http://i32.tinypic.com/311nc08.jpg
后记忆用法图:http://i51.tinypic.com/29goill.jpg

几个月来,我每隔几天就无法重启服务器,但在过去的14个小时里,内存使用量没有增加。

我用来帮助开发服务器的每个教程,示例,演示文稿和书籍都省略了一个关于IO :: Socket :: SSL的非常重要的事实。每个在线程应用程序中使用该模块的人都会更好地倾听。没有人曾经强调IO :: Socket :: SSL文档中的最后一行,这让我非常愚蠢地假设我创建的任何套接字,就像几乎任何其他数据结构一样,一旦超出范围就会被释放(并且是的) ,我确实知道该规则的例外情况)。我以为我会帮助每个人,并提出我所指的界限。

  

... IO :: Socket :: SSL套接字将保持打开状态,直到程序结束或您明确关闭它们。这是因为需要循环引用以使IO :: Socket :: SSL套接字同时像对象和glob引用一样起作用。
  http://search.cpan.org/dist/IO-Socket-SSL/SSL.pm#LIMITATIONS

我从来没有意识到这些插座中有一个循环引用的事实,如果我不知道它们,那么我读过的每个人的博客和书籍都不知道(因此呼出) )。

你可以想象,这有一个非常简单的解决方法。在我的线程的工作循环中,每次迭代都会创建一个套接字,我只需在底部放置一个eval { close $socket; };undef $socket;,以确保在处理下一个客户端之前它被关闭。我启动了我的服务器并等待并观察内存使用率是否稳定,如我在第二张图中所示。因此,在对此问题进行两个月的故障排除后,我终于找到了解决方案。我希望这为任何其他业余爱好者使用套接字编程提供了一些见解。感谢所有提供答案/意见/建议的人,每一点都有所帮助,并且它有助于提供一个反复思考的地方。

答案 2 :(得分:1)

尝试升级threads.pm和threads :: shared。升级到perl 5.12.1也是一个好主意。

答案 3 :(得分:1)

我遇到了与5.10相同的问题,尽管有许多抗议说新的Perl在使用线程时没有泄漏内存,但Perl在使用线程时泄露了内存。

我的解决方案是使用Thread::Pool::Simple创建一个线程池并使用它而不是创建新线程。在我的情况下,我并不期望有很多同时的线程,也不会让它们持续很长一段时间(最多可能是30秒)。我不知道这对你来说是不是一个选择,但如果你真的只是让你的线程处理简单的任务,那么它可能就是。