【问题标题】:How to clear memory after message_string() in perl如何在perl中的message_string()之后清除内存
【发布时间】:2014-12-23 13:28:13
【问题描述】:

我使用 perl v5.18.2 和 lib Mail::IMAPClient 3.35 版。如果电子邮件大小(附件)很大,方法message_string 会占用大量内存。如果它在使用后释放,那将不是问题。但是使用这种方法的恶魔并没有释放这块内存。为了检查,我使用 Memory::Usage lib 和大约 30MB 大小的电子邮件。

time    vsz    (  diff)    rss   (  diff) shared (  diff)   code (  diff)   data  (  diff)
         0  34212  ( 34212)  21272   ( 21272)   5124 (  5124)   1504 (  1504)  16208  ( 16208) before message_string
        18  136180 ( 101968)  120632 ( 99360)   5148 (    24)   1504 (     0)  118156 ( 101948) after message_string

在致电message_string 之后,我做split

$message = $imap->message_string($msg); ($header, $body) = split /\n\h*\n/, $message, 2;

time    vsz    (  diff)    rss  (  diff) shared (  diff)   code (  diff)   data  (  diff)
     0  108708 ( 108708)  87560 ( 87560)   5148 (  5148)   1504 (  1504)  90684  ( 90684) before split
     4  141240 ( 32532)  120332 ( 32772)   5148 (     0)   1504 (     0)  123216 ( 32532) after split

这两行占用了 daemon 所用资源的 80-90%。

Bug on cpan

如果您用message_string 方法帮助我,我将不胜感激。 有没有比split更便宜的方法?

方法来源:

sub message_string {
    my $self = shift;
    my $msg  = shift;
    my $expected_size = $self->size($msg);
    return undef unless(defined $expected_size);    # unable to get size
    my $cmd  =      $self->has_capability('IMAP4REV1')              ? 
                "BODY" . ( $self->Peek ? '.PEEK[]' : '[]' )         : 
                "RFC822" .  ( $self->Peek ? '.PEEK' : ''  )     ;

    $self->fetch($msg,$cmd) or return undef;

    my $string = "";

    foreach my $result  (@{$self->{"History"}{$self->Transaction}}) { 
              $string .= $result->[DATA] 
        if defined($result) and $self->_is_literal($result) ;
    }      
    # BUG? should probably return undef if length != expected
    if ( length($string) != $expected_size ) { 
        carp "${self}::message_string: " .
            "expected $expected_size bytes but received " . 
            length($string) 
            if $self->Debug or $^W; 
    }
    if ( length($string) > $expected_size ) 
    { $string = substr($string,0,$expected_size) }
    if ( length($string) < $expected_size ) {
        $self->LastError("${self}::message_string: expected ".
            "$expected_size bytes but received " . 
            length($string)."\n");
        return undef;
    }
    return $string;
}

【问题讨论】:

    标签: perl memory split


    【解决方案1】:

    一旦内存被程序 (Perl) 使用,您就不能让它返回给操作系统。它可能会稍后返回或不返回。这就是为什么许多守护进程偶尔会自行重启的原因。

    另请参阅FAQ

    【讨论】:

    • 那么我的解决方案是什么?
    猜你喜欢
    • 2015-05-24
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    • 1970-01-01
    • 2019-08-14
    • 2020-09-06
    • 2011-05-10
    相关资源
    最近更新 更多