【发布时间】:2011-09-14 22:40:14
【问题描述】:
tl;dr:当 Perl httpd 进程内存不足时如何转储 perl 堆栈跟踪。
我们有一个 mod_perl 2 服务器、Perl 5.8.8、RHEL 5.6、Linux 2.6.18。
非常偶然且不可预测的是,子 httpd 进程开始以惊人的速度耗尽所有可用内存。我们至少使用了 BSD::Resource::setrlimit(RLIMIT_VMEM, ...),以便进程在关闭服务器之前因“内存不足”而终止。
我们不知道这发生在代码中的什么位置,而且如果没有数小时的负载测试就很难重现。
我们真正想要的是一种在进程耗尽内存之前获取 Perl 堆栈跟踪的方法,这样我们就知道是什么代码导致了这种情况。不幸的是,“内存不足”是untrappable error。
以下是我正在考虑的选项,每个选项都有其缺点:
1) 使用$^M emergency memory pool。要求我们使用 -DPERL_EMERGENCY_SBRK 和 -Dusemymalloc 重新编译 perl。
2) 放入大量日志语句,然后分析日志以查看进程在哪里停止。
3) 编写一个持续扫描 httpd 进程池的外部脚本,如果它发现一个使用大量内存,则向它发送一个 USR2 信号(我们已安排转储堆栈跟踪)。
4) 不知何故让进程持续监控自己的内存,并在内存变高但在“内存不足”错误之前转储堆栈跟踪。
谢谢!
乔恩
【问题讨论】:
-
是否可以在Devel::NYTProf下运行进程?
-
就像我说的,这个问题很少发生 - 假设在一个小时的负载测试之后 - 所以如果我们在分析或大量日志记录下运行,我们必须收集大量数据。另外有一个可以在生产中工作的解决方案会很好,显然我们不能在 Devel::NYTProf 下运行。
标签: perl memory out-of-memory