簡體   English   中英

Perl內存使用情況分析和泄漏檢測?

[英]Perl memory usage profiling and leak detection?

我在Perl上編寫了一個在Linux上運行的持久網絡服務。

不幸的是,隨着它的運行,其駐留堆棧大小(RSS)只是緩慢但肯定地增長,增長和增長。

盡管我努力消除所有不需要的哈希鍵並刪除對象的所有引用,否則會導致引用計數保留在原位並阻礙垃圾收集。

是否有任何好的工具可以在Perl程序中分析與各種本機數據原語,祝福散列引用對象等相關的內存使用情況? 你用什么來追蹤內存泄漏?

我不習慣在Perl調試器或任何各種交互式分析器中花費時間,因此我們將非常感謝溫暖,溫和,非深奧的反應。 :-)

您可以在其中一個對象中使用循環引用。 當垃圾收集器出現以釋放此對象時,循環引用意味着該引用引用的所有內容永遠不會被釋放。 您可以使用Devel :: CycleTest :: 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實現的模塊。 如果它可能是你自己的代碼,那么找一些可能有些可疑的東西:

  • 絕對使用Inline :: C或XS代碼
  • 直接使用引用,例如\\@list\\%hash ,而不是像[qw(foo bar)]這樣的預分配引用(前者創建了另一個可能丟失的引用;在后者中,只有一個引用需要擔心,通常存儲在本地詞法標量中
  • 間接操作變量,例如$$foo ,其中$foo被修改,這可能導致變量的自動更新(盡管你需要禁用strict 'refs'檢查)

我最近使用NYTProf作為大型Perl應用程序的分析器。 它不跟蹤內存使用情況,但它會跟蹤所有已執行的代碼路徑,這有助於找出泄漏源自何處。 如果您泄漏的是稀缺資源(如數據庫連接),那么在分配和關閉它們的位置進行跟蹤會大大有助於發現泄漏。

Perl手冊中包含了一個很好的指南: 調試Perl內存使用情況

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM