我有一个使用 POE 的应用程序,它有大约 10 个会话来执行各种任务。随着时间的推移,应用程序开始消耗越来越多的 RAM,即使应用程序有 80% 的时间处于空闲状态,这种使用量也不会下降。我目前唯一的解决方案是经常重新启动该过程。
我不允许在这里发布我的代码,所以我意识到很难获得帮助,但也许有人可以告诉我我能做些什么来找出自己?
不要期望进程大小会减小。在进程终止之前,内存不会释放回操作系统。
也就是说,您可能在某处的数据结构中有引用循环吗?AFAIK,perl 垃圾收集器无法整理引用循环。
您是否在任何地方使用任何 XS 模块?里面可能隐藏着泄漏。
看起来Test::Valgrind是一个搜索内存泄漏的工具。虽然我自己从来没有使用过它(但我使用普通的 valgrind 和 C 源代码)。
Perl 不能解析引用环。要么你有僵尸(你可以通过 ps axl 检测到),要么你有内存泄漏(参考环/圆)
有很多程序可以检测内存泄漏。strace、mtrace、Devel::LeakTrace::Fast、Devel::Cycle
一个猜测:你的程序在运行期间执行一个循环;在这个循环中,每次发生某些情况时,您可能会为缓冲区(或更多)分配内存;由于范围永远不会退出,内存仍然存在并且永远不会被清理。我建议你检查类似的东西。如果是这种情况,请将分配代码放在您从循环调用的子程序中,并且在返回循环时它将超出范围并被清理。
一种技术是定期将 $POE::Kernel::poe_kernel 的内容转储到以时间或序列命名的文件中。$poe_kernel 是跨越所有已知会话及其堆内容的树的根。如果引用了泄漏的内存,则快照应该单调增长。您将能够通过将早期快照与后来的快照进行比较来找出泄漏的内容。
您可以导出 POE_ASSERT_DATA=1 以启用 POE 的内部数据一致性检查。我不指望它会出现问题,但如果确实如此,我会很高兴收到错误报告。