Opened 5 years ago

Closed 5 years ago

#1485187 closed Bugs (fixed)

[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 (1)

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

Download all attachments as: .zip

Change History (4)

Changed 5 years ago by jeblair

Patch to index.php and imap.inc

comment:1 Changed 5 years ago by alec

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

comment:2 Changed 5 years 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.

comment:3 Changed 5 years ago by alec

  • Resolution set to fixed
  • Status changed from new to closed

Fixed in [d5c53994].

Note: See TracTickets for help on using tickets.