Skip Menu |

This queue is for tickets about the Mail-IMAPClient CPAN distribution.

Report information
The Basics
Id: 61292
Status: resolved
Priority: 0/
Queue: Mail-IMAPClient

People
Owner: PLOBBES [...] cpan.org
Requestors: gilles.lamiral [...] laposte.net
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 3.26



CC: imapsync <imapsync [...] linux-france.org>
Subject: [Mail-IMAPClient] Memory consumption with message_string() and append()
Date: Mon, 13 Sep 2010 06:44:11 +0200
To: bug-Mail-IMAPClient [...] rt.cpan.org
From: Gilles LAMIRAL <gilles.lamiral [...] laposte.net>
Hello, With message_string() Mail-IMAPClient consumes memory about 7 or 8 times a message size. With append() Mail-IMAPClient consumes memory about 7 or 8 times a message size. Example: For a simple transfer done with this code: ... my $string = $imap->message_string($msg); $imap->append('INBOX.Trash', $string); The memory consumed with this simple code is about 18 times the size of the message, the size of $string here. To transfer a big message of 50 MB the machine need at least 900 MB of RAM. I attached a perl script to show memory consumption on a Unix machine. Just put a big message (10 MB) in folder INBOX.bigmail and run it like this: ./memory_consumption 127.0.0.1 user user_password INBOX.bigmail Output: ./memory_consumption 127.0.0.1 user user_password INBOX.bigmail 1 main, ./memory_consumption, 31, main::memory_consumption PID %CPU COMMAND VSZ RSS SZ 18979 0.0 perl 9192 5072 3312 -------------------------------------------------------------------------------- size 1 14370501 main, ./memory_consumption, 36, main::memory_consumption PID %CPU COMMAND VSZ RSS SZ 18979 37.0 perl 121480 117368 115600 |||||| after message_string-------^^^^^^ -------------------------------------------------------------------------------- main, ./memory_consumption, 38, main::memory_consumption PID %CPU COMMAND VSZ RSS SZ 18979 66.8 perl 261932 257888 256052 |||||| after append---------------^^^^^^ ... 261932000/14370501 = 18 Why Mail-IMAPClient allocates so much memory for just a string copy? I can understand 2 or even 3 times allocation size but 8 is quite a big factor. I have no patch yet to reduce this memory consumption. Thanks in advance if you can explain or do something with this issue. ==== Numbers perl v5.10.0 or v5.8.8 uname -a Linux plume 2.6.18-6-k7 #1 SMP Fri Feb 19 23:58:00 UTC 2010 i686 GNU/Linux Linux petite 2.6.28-19-generic #64-Ubuntu SMP Wed Aug 18 20:55:57 UTC 2010 i686 GNU/Linux Mail-IMAPClient-3.25 -- Au revoir, 09 51 84 42 42 Gilles Lamiral. France, Baulon (35580) 06 20 79 76 06
#!/usr/bin/perl use warnings; use strict; use English; use Mail::IMAPClient; $ARGV[3] or die "usage: $0 host user password folder\n"; my $host = $ARGV[0]; my $user = $ARGV[1]; my $password = $ARGV[2]; my $folder = $ARGV[3]; my $imap = Mail::IMAPClient->new(); $imap->Debug(0); $imap->Server($host); $imap->connect() or die; $imap->User($user); $imap->Password($password); $imap->login() or die; $imap->Uid(1); $imap->Peek(1); $imap->Clear(1); #print map {"$_\n"} $imap->folders(); $imap->select($folder) or die; my @msgs = $imap->messages or die "Could not messages: $@\n"; print "@msgs\n"; print memory_consumption(); foreach my $msg (@msgs) { my $size = $imap->size($msg); print "size $msg $size\n"; my $string = $imap->message_string($msg); print memory_consumption(); $imap->append('INBOX.Trash', $string); print memory_consumption(); } $imap->close(); print memory_consumption(); sub memory_consumption { my @PID = (@_) ? @_ : ($PROCESS_ID); my $val; my ($package, $filename, $line, $subroutine) = caller(0); $val = "$package, $filename, $line, $subroutine\n"; $val .= qx{ ps o pid,pcpu,comm,vsz,rss,size @PID }; $val .= '-' x 80 . "\n"; return($val); }
Hi Gilles. Thanks for the bug report! Sorry for the delayed response. Are you using a value of 5 for 'Clear'? If so, have you tried reducing that to 1 to see if that gives you better memory usage? Unless the mechanism for storing IMAP command history goes away completely there will always be some wasted memory but there is probably room for improvement.
CC: DJKERNEN__NO_SOLICITING__ [...] cpan.org
Subject: Re: [rt.cpan.org #61292] [Mail-IMAPClient] Memory consumption with message_string() and append()
Date: Tue, 21 Sep 2010 01:57:35 +0200
To: bug-Mail-IMAPClient [...] rt.cpan.org
From: Gilles LAMIRAL <gilles.lamiral [...] laposte.net>
Hello Phil, Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=61292 > > > Are you using a value of 5 for 'Clear'?
I use Clear(1) Show quoted text
> If so, have you tried reducing that to 1 to see if that gives you > better memory usage? Unless the mechanism for storing IMAP command > history goes away completely there will always be some wasted memory but > there is probably room for improvement.
Yes. I wrote a dirty (but working) message_string_raw() function reducing the memory ratio from 12 to 4. I have to do the same for append() since with append() the ratio goes to 21. 20 times the size of the message for just an imap append is quite expensive. I check the behaviour with 10MB and 50MB messages and the little script needs more than 1GB of memory. Thanks users they're not transfering CDs and DVDs iso images by email! -- Au revoir, 09 51 84 42 42 Gilles Lamiral. France, Baulon (35580) 06 20 79 76 06
I have committed several changes to the code to bring memory usage under control. If you would like me to send you a beta/developer's release please let me know. I will probably release 3.26 early next week unless problems are found. Here are the related Changelog entries: - *rt.cpan.org#61292: memory consumption with message_string()/append() rt.cpan.org#61806: Major problem with one function in IMAPClient [Gilles Lamiral, Casey Duquette] + use @_ / $_[<num>] in critical places to avoid pass by value memory overhead + use in memory files in a few critical places as that code path in Mail::IMAPClient is significantly more efficient with internal memory usage + *new attribute Maxappendstringlength used by append() and append_string() holds the size (in bytes, default 1 MiB) that triggers when message SCALAR(s) passed to these methods will be treated as an in memory file. + *append() and append_string() now call append_file() and use an im memory file when length($message) is greater than Maxappendstringlength; other minor code cleanup + *message_string() now calls message_to_file() and uses an in memory file + refactor message_to_file() to use internal _imap_uid_command() + update _read_line() to be more efficient w/CPU in critical section by pulling isa() checks out of main loop also conserve memory by not storing an extra copy of LITERAL data if the data was put into a filehandle from the caller + Memory/working set (KB) comparison (Perl 5.10 cygwin Win7): - test: message_string on 6.1M msg and then append 6.1M msg version | start | after message_string | after append --------+-------+----------------------+------------- 2.2.9 | 7624 | 74404 | 131896 3.25 | 7716 | 74408 | 156532 3.26 | 7684 | 33372 | 42608
Mail::IMAPClient 3.26 has been released to CPAN. Please install it if you get a chance and let me know if you run into any more problems, thanks!