Re: leak?
Jon Wilson <[email protected]> Tue, 24 Aug 2004 19:12:45 +0100
| Newsgroups | gmane.comp.lang.perl.modules.mail-box |
|---|---|
| Message-ID | <[email protected]> |
Hi Mark, Mark Overmeer wrote: > * Jon Wilson ([email protected]) [040824 14:33]: > >>I've noticed a memory leak when I clone messages. Test code and test >>message attached. It's probably some kind of circular reference. It >>doesn't happen if I don't clone the message. > > > When you remove the clone() from your code, it still leaks memory. If I increase the number of times the mbox is read, but with the "clone" operation off, the number of allocated objects left at the end of the script does not increase appreciably. If the clone operation is on, the number increases by a lot! Count of allocated objects at end of script: 100 runs, clone off: 39386 1000 runs, clone off: 39384 10000 runs, clone off: 39384 100 runs, clone on: 40521 1000 runs, clone on: 43220 10000 runs, clone on: 70220 > I am not familiar with Devel::Leak, but does it understand > Scalar::Util::weaken() ? I have used that a lot, but may have > missed one or two spots. Devel::Leak just gives a count of the number of "things" allocated by perl. > When you open an mbox folder, it will be lazy: only the headers will > be taken in memory. When you clone the messages, the bodies will > get stored in memory as well. So: it is very normal that the > memory usage explodes when you go through the whole folder. This is not what I am doing. I am opening a folder, looking at the messages (one in this case), and closing the folder. Repeat. Since the folder object passes out of scope at the end of the loop, any objects (and hence memory) related to it should get destroyed. But this doesnt seem to be happening. > If you are willing to persue the "leak" further, than be my guest. > There may be many reasons within Perl, Devel::Leak, Scalar::Util, or > even Mail::Box which produce this result. My experience with large codebases of object orientated perl code is that the problem is usually a circular reference within some object or group of objects. So when the folder object passes out of scope, not everything is destroyed, because references still exist. I'm not familiar with exactly how the Mail::Box internals are arranged(I only started using it yesterday). But consider something like the following. If some message object contained a reference to the "next" message in the mailbox. If the last message contains a reference to the first one, then there is a circular reference, and Perl will not really destroy the objects, even though the variables representing each object pass out of scope. Alternatively the problem lies in the Mail::Box::Parser::C code. I can investigate further when I get time, but perhaps someone on this list knows the internals well enought to spot the problem quickly. > By the way: I see no reason for creating a clone() in normal applications. > When you move messages from one folder to the other, MailBox will do that > as efficiently as possible for you. (see $msg->move, $msg->copy, etc) I need to open several large read-only mbox files (mail archives), select certain messages from them (a user's mail) and save these to another mbox (user.INBOX.i.must.not.delete.all.my.mail.sorry). The number of messages is BIG so leaks are important to me. "move" is clearly not appropriate in this case. The Mail::Message documentation has no reference for "copy", only for "clone". Or am I missing something here? Actually I want to copy to an IMAP folder, not another mbox, but I'm having problems with that. More news on that later maybe. Thanks for the quick reply, Jon