Ticket #1485187 (closed Bugs: fixed)

Opened 5 months ago

Last modified 3 months ago

[PATCH] Memory leak when downloading attachments

Reported by: jeblair Owned by:
Priority: 5 Milestone: 0.2-beta
Component: PHP backend Version: 0.2-alpha
Severity: major Keywords:
Cc:

Description

We observed unusally high Apache memory usage when downloading large attachments in 0.2-alpha. The effect is cumulative, suggesting a memory leak. This is a serious problem -- multiple users downloading attachments were able to cause our webmail servers to run out of memory.

Steps to replicate problem

If you want to replicate the problem, here are the steps I used:

1) Prepare your mailbox with several emails with large (suggest 2MB to 10MB or more) binary (so they will be base64 encoded) attachments. In order to see a cumulative effect, you will need to download attachments from different emails.

2) Use the prefork MPM with these settings:

<IfModule prefork.c>
StartServers       1
MinSpareServers    1
MaxSpareServers    1
ServerLimit        1
MaxClients         1
MaxRequestsPerChild  4000
</IfModule>

This will cause there to be only one Apache process handling your requests, so that you can see the effect on memory by watching a single process.

3) Browse to each message in turn and download the attachment. You should see the memory usage of the httpd process increase each time. It may baloon a bit, but it will always return to a level higher than the previous message. For instance, in my testing, I saw the following:

19MB resident after opening a folder to load RC's php files
24MB resident after d/l a 2MB attachment
29MB resident after d/l a 3MB attachment
53MB resident after d/l a 15MB attachment

With, of course, corresponding increases in the virtual size of the process as well (from 345MB to 379MB).

After applying the fix below, and repeating the experiment, the memory usage does not increase from the base level of 19MB resident after downloading several attachments.

Solution

I've identified two contributing factors. The first is that the index.php sets output buffering before initializing RCMAIL, so the check to turn of output buffering when downloading attachments doesn't work. Simply moving the initializer for RCMAIL to before the buffering code causes that to work as intended.

Secondly, in imap.inc, the flush() call after base64_decode causes PHP to use more memory than otherwise. It is not needed, and removing it returns memory usage to normal patterns.

I'm attaching a patch that makes these changes.

Attachments

rc-memory.diff (1.1 kB) - added by jeblair 5 months ago.
Patch to index.php and imap.inc

Change History

Changed 5 months ago by jeblair

Patch to index.php and imap.inc

Changed 4 months ago by alec

index.php was fixed, but I'm not sure about the second part of the patch

Changed 3 months ago by ziba

I followed the steps and reproduced the memory leak. The second part of the patch was necessary for me to stop the leak.

Changed 3 months ago by alec

  • status changed from new to closed
  • resolution set to fixed

Fixed in r1682.

Note: See TracTickets for help on using tickets.