tl; dr:如何在Perl httpd進程內存不足時轉儲perl堆棧跟蹤。從Perl獲取堆棧跟蹤「內存不足」錯誤
我們有一個mod_perl 2服務器,Perl 5.8.8,RHEL 5.6,Linux 2.6.18。
偶爾和不可預知的是,子httpd進程開始以驚人的速度使用所有可用內存。我們至少使用了BSD :: Resource :: setrlimit(RLIMIT_VMEM,...),這樣在關閉服務器之前,進程就會因「內存不足」而死亡。
我們不知道在代碼中發生了什麼,並且在沒有負載測試小時的情況下很難重現。
我們真正想要的是一種在進程內存耗盡之前獲得Perl堆棧跟蹤的方法,因此我們知道是什麼代碼導致了這種情況。不幸的是,「內存不足」是untrappable error。
這裏是我考慮的選項,各自有各自的缺點:使用$^M emergency memory pool
1)。要求我們用-DPERL_EMERGENCY_SBRK和-Dusemymalloc重新編譯perl。
2)輸入大量的日誌語句,然後分析日誌以查看過程停止的地方。 3)編寫一個不斷掃描httpd進程池的外部腳本,如果它看到一個使用大量內存的腳本,則向它發送一個USR2信號(我們已經安排轉儲堆棧跟蹤)。
4)以某種方式持續監視自己的內存,並在內存變高但在「內存不足」錯誤之前轉儲堆棧跟蹤。
謝謝!
喬恩
是否可以在[Devel :: NYTProf](http://search.cpan.org/perldoc?Devel::NYTProf)下運行該進程? – 2011-06-14 18:53:14
就像我說的那樣,這個問題很少發生 - 比如在一小時的負載測試之後 - 所以如果我們運行在性能分析或重度日誌記錄的情況下,我們將不得不收集大量的數據。另外,解決方案可以在生產環境中工作,顯然,我們無法在Devel :: NYTProf下運行。 – 2011-06-14 19:07:23