[英]Perl memory usage profiling and leak detection?
我在Perl上編寫了一個在Linux上運行的持久網絡服務。
不幸的是,隨着它的運行,其駐留堆棧大小(RSS)只是緩慢但肯定地增長,增長和增長。
盡管我努力消除所有不需要的哈希鍵並刪除對象的所有引用,否則會導致引用計數保留在原位並阻礙垃圾收集。
是否有任何好的工具可以在Perl程序中分析與各種本機數據原語,祝福散列引用對象等相關的內存使用情況? 你用什么來追蹤內存泄漏?
我不習慣在Perl調試器或任何各種交互式分析器中花費時間,因此我們將非常感謝溫暖,溫和,非深奧的反應。 :-)
您可以在其中一個對象中使用循環引用。 當垃圾收集器出現以釋放此對象時,循環引用意味着該引用引用的所有內容永遠不會被釋放。 您可以使用Devel :: Cycle和Test :: Memory :: Cycle檢查循環引用。 有一件事要嘗試(雖然它可能在生產代碼中變得昂貴,所以我在未設置調試標志時禁用它)是在析構函數內檢查所有對象的循環引用:
# make this be the parent class for all objects you want to check;
# or alternatively, stuff this into the UNIVERSAL class's destructor
package My::Parent;
use strict;
use warnings;
use Devel::Cycle; # exports find_cycle() by default
sub DESTROY
{
my $this = shift;
# callback will be called for every cycle found
find_cycle($this, sub {
my $path = shift;
foreach (@$path)
{
my ($type,$index,$ref,$value) = @$_;
print STDERR "Circular reference found while destroying object of type " .
ref($this) . "! reftype: $type\n";
# print other diagnostics if needed; see docs for find_cycle()
}
});
# perhaps add code to weaken any circular references found,
# so that destructor can Do The Right Thing
}
您可以使用Devel :: Leak來搜索內存泄漏。 但是,文檔非常稀疏...例如,只有將$ handle引用傳遞給Devel::Leak::NoteSV()
?
f我找到了答案,我將編輯此回復。
好吧,事實證明使用這個模塊非常簡單(代碼從Apache :: Leak無恥地竊取):
use Devel::Leak;
my $handle; # apparently this doesn't need to be anything at all
my $leaveCount = 0;
my $enterCount = Devel::Leak::NoteSV($handle);
print STDERR "ENTER: $enterCount SVs\n";
# ... code that may leak
$leaveCount = Devel::Leak::CheckSV($handle);
print STDERR "\nLEAVE: $leaveCount SVs\n";
我會在中間部分放置盡可能多的代碼,盡可能將leaveCount檢查盡可能接近執行結束(如果你有的話) - 在大多數變量被盡可能解除分配后(如果你不能得到)一個變量超出范圍,你可以為它分配undef以釋放它所指向的任何東西)。
接下來要嘗試什么(不知道在上面的Alex問題之后這是否最好放在評論中):我接下來會嘗試什么(除了Devel :: Leak):
嘗試消除程序的“不必要”部分,或將其划分為單獨的可執行文件(它們可以使用信號進行通信,或者使用命令行參數相互調用) - 目標是將可執行文件分解為最小量代碼仍然表現出不良行為 。 如果您確定不是您的代碼正在執行此操作,請減少您正在使用的外部模塊的數量,尤其是那些具有XS實現的模塊。 如果它可能是你自己的代碼,那么找一些可能有些可疑的東西:
\\@list
或\\%hash
,而不是像[qw(foo bar)]這樣的預分配引用(前者創建了另一個可能丟失的引用;在后者中,只有一個引用需要擔心,通常存儲在本地詞法標量中 $$foo
,其中$foo
被修改,這可能導致變量的自動更新(盡管你需要禁用strict 'refs'
檢查) 我最近使用NYTProf作為大型Perl應用程序的分析器。 它不跟蹤內存使用情況,但它會跟蹤所有已執行的代碼路徑,這有助於找出泄漏源自何處。 如果您泄漏的是稀缺資源(如數據庫連接),那么在分配和關閉它們的位置進行跟蹤會大大有助於發現泄漏。
Perl手冊中包含了一個很好的指南: 調試Perl內存使用情況
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.