我在Windows 2003 Server上使用ActiveState Perl 5.6,并且遇到了一些内存泄漏问题.是否有任何好的工具(甚至可以提供线索的坏工具),我可以使用它来帮助找到它们.
我正在运行一个包含10个线程的Perl服务器.它们永远不会在程序退出之前被销毁,但这是我打算尽可能多的正常运行时间,所以这就是为什么这对我来说是一个问题.线程多次处理一个简单的任务.当我启动服务器并启动所有线程时,我发现我有288.30 MB的空闲时间.经过每个线程的几次迭代后,它报告285.96 MB空闲.这并不是那么糟糕.可能只是在这些迭代过程中,一些堆栈空间被分配或者某些东西.但是15分钟后,可用内存下降到248.24 MB!我的记忆发生了什么?现在,有趣的是,它已达到稳定水平.它继续慢慢消耗,但不像最初那么快.
我在线程的每次迭代之后打印出可用空间,这样我就可以慢慢看到它.现在有趣的是它不会每次都减少.有时,迭代后空闲内存保持不变.
我正在使用从Linux 2.6上的源代码构建的Perl 5.8.8
有没有人有任何想法,甚至建议可能导致这种情况的原因是什么?我正在考虑将我的Perl升级到更高版本以排除Perl核心内部的内存泄漏.
更新:这可能是一个线程堆栈大小问题?我可以为堆栈分配比我需要的更多内存吗?当我创建我的线程时,我不会更改默认设置.我是不是该?线程doc说默认值通常为16MB,具体取决于系统.16x10线程= 160MB - >这可能是罪魁祸首.思考?
更新:我构建并安装了Perl 5.12.1并重建了模块和所有内容.已经运行了大约一个小时的脚本,这是我注意到的.内存使用现在可以管理,但并不理想.
还有其他想法吗?我可以试试吗?我已经无法解决所有变数了.
更新:我真的想继续使用glibc重新编译Perl作为最后的手段,因为我发现一些报告,在某些版本的Linux上会出现段错误.所以自从我上次发布以来,我进一步探讨了哈希中循环的可能性.一无所获.所以我花了最后几天分析我的子程序并缓存在另一次迭代中使用的任何东西.每次都会重新创建很多新东西,而Perl并没有清理所有内容,即使我明确地解决了这一切.所以如果它不合作,我就不会破坏它.将看看缓存我的对象是否有帮助.稍后会发布内存使用情况统计信息.
更新:嗯,非常奇怪.即使在缓存我的数据以便以后重用之后,内存也会以大致相同的速率上升.它现在开始更高,因为我正在缓存,但随后它继续上升,即使它主要是使用我的缓存对象.这令人费解.猜猜是时候尝试一下glibc ......否则这只是选择Perl的一个缺点,并且必须每隔几天重新启动一次服务器.
更新:尝试没有缓存,没有glibc,再次.工作正常一段时间,几个小时,然后它开始增长.只是想让你看到一个图表.
http://tinypic.com/r/311nc08/3
http://i32.tinypic.com/311nc08.jpg
更新:这是一个日志的摘录,记录每个线程在大约一分钟之前和之后的可用内存.也许这可以帮助别人更好地理解问题.它看起来有点稳定,然后每隔一段时间就会吃掉更多的内存.在这里,我失去了近40 MB!
[9:8:30, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 253.812736MB (obj cache: 136)
[9:8:30, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 253.812736MB (obj cache: 136)
[9:8:34, Fri Jul 23, 2010] [204] Sending data to thread
[9:8:34, …Run Code Online (Sandbox Code Playgroud) 我使用File :: Slurp在一个大文件中啜饮但是考虑到文件的大小,我可以看到我必须在内存中使用它两次,或者可能因为变成16位unicode而膨胀.我怎样才能最好地诊断Perl中的那种问题?
我输入的文件大小为800mb,我的perl进程正在分析该数据在运行时分配的大约1.6gb.
我意识到我对这个问题的理由可能是错的,但我不确定证明/反驳我的理论的最有效方法.
更新:
我从嫌疑人名单中删除了狡猾的字符编码.看起来我在某个时候复制变量,我只是无法弄清楚在哪里.
更新2:
我现在已经做了一些调查,发现它实际上只是从File :: Slurp获取导致问题的数据.我查看了文档,发现我可以让它返回一个scalar_ref,即
my $data = read_file($file, binmode => ':raw', scalar_ref => 1);
Run Code Online (Sandbox Code Playgroud)
然后我没有得到记忆的膨胀.在我的情况下获取数据时,这是有道理的并且是最合理的事情.
关于查看存在哪些变量等信息通常有帮助,但感谢.
我正在为Perl的时事通讯写一个守护进程.
守护程序将在服务器上全天候运行.它几乎一直都与postgresql数据库有一个活动的连接.
我没有那么多Perl的经验,所以如果你们中的一些人可以分享以下信息,我会很高兴:
如何限制RAM.我不想离开公羊.正如我所说,这个程序将一直作为守护进程运行而不会被停止.
在编写这样的守护进程时我应该注意什么?