【发布时间】: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%。
如果您用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;
}
【问题讨论】: