homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: memory leak with generators
Type: resource usage Stage:
Components: Interpreter Core Versions: Python 3.2, Python 3.3, Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: flox, hynek, ned.deily, pitrou, r.david.murray, ronaldoussoren
Priority: normal Keywords:

Created on 2012年08月13日 09:25 by flox, last changed 2022年04月11日 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
testiterbug.py flox, 2012年08月13日 09:25
Messages (10)
msg168072 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2012年08月13日 09:25
Hello,
I noticed a large memory consumption in my application.
I tracked it down to be a problem with garbage collection of generator locals.
The issue was noticed in 2.6 first. Then I reproduced it in 2.7.
The test case finds some leak in 3.3 too, it seems.
msg168082 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2012年08月13日 12:07
Though, I cannot reproduce on Debian Squeeze (2.6.6 deb or 2.7 from source) or Ubuntu (2.7.2+ or 3.2).
Someone on OS X might confirm the same issue.
This is python 2.7.3 installed from source (using perlbrew) and GCC 4.2.1.
The output of the script is:
$ python testiterbug.py
2.7.3 (default, May 20 2012, 19:54:58)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]
[row for row in iterit(16777216)]
Memory usage: 9.3 MB
[row for row in iterit(8388608)]
Memory usage: 266.6 MB
msg168083 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2012年08月13日 12:08
I don't mean perlbrew, but homebrew (an OS X package manager to install from source).
msg168088 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2012年08月13日 12:22
I can reproduce this on an OSX 10.8 system, both using python 2.7 and python 3.3. The growth is significantly less using python 3.3.
What's odd is that the growth does not occur when both test_iter calls use 1<<24 as the argument (or larger values).
If I'd had to guess I'd say that the free implementation doesn't return a buffer to the system for smaller blocks and does do it for larger buffers.
msg168089 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2012年08月13日 12:23
BTW. I don't think this is a memory leak, the amount of memory used doesn't increase when there are more calls to test_iter(1<<23).
msg168108 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2012年08月13日 14:09
I've added calls to vmmap to the script (using os.system) to check my guesss.
The relevant bit after the call to test_iter(1<<24):
REGION TYPE VIRTUAL
=========== =======
MALLOC 405.9M see MALLOC ZONE table below
MALLOC guard page 32K
MALLOC metadata 376K
STACK GUARD 56.0M
Stack 8192K
VM_ALLOCATE 4K
__DATA 1720K
__LINKEDIT 53.4M
__TEXT 12.1M
__UNICODE 544K
shared memory 8K
=========== =======
TOTAL 538.1M
 VIRTUAL ALLOCATION BYTES
MALLOC ZONE SIZE COUNT ALLOCATED % FULL
=========== ======= ========= ========= ======
DefaultMallocZone_0x100436000 404.9M 414059 390.6M 96%
DispatchContinuations_0x1007dc000 1024K 17 1056 0%
=========== ======= ========= ========= ======
TOTAL 405.9M 414076 390.6M 96%
Memory usage: 14.3 MB
And after the call to test_iter(1<<13)
REGION TYPE VIRTUAL
=========== =======
MALLOC 208.9M see MALLOC ZONE table below
MALLOC freed, no zone 456.0M
MALLOC guard page 32K
MALLOC metadata 392K
STACK GUARD 56.0M
Stack 8192K
VM_ALLOCATE 4K
__DATA 1720K
__LINKEDIT 53.4M
__TEXT 12.1M
__UNICODE 544K
shared memory 8K
=========== =======
TOTAL 797.1M
 VIRTUAL ALLOCATION BYTES
MALLOC ZONE SIZE COUNT ALLOCATED % FULL
=========== ======= ========= ========= ======
DefaultMallocZone_0x100436000 207.9M 209467 197.0M 94%
DispatchContinuations_0x1007dc000 1024K 17 1056 0%
=========== ======= ========= ========= ======
TOTAL 208.9M 209484 197.0M 94%
Memory usage: 462.6 MB
The total amount of "memory usage" is grown by about 450 MBytes (according to psutils). This is explained by the change in MALLOC memory, before:
MALLOC 405.9M see MALLOC ZONE table below
MALLOC guard page 32K
MALLOC metadata 376K
Total: about 406 MByte
After:
MALLOC 208.9M see MALLOC ZONE table below
MALLOC freed, no zone 456.0M
MALLOC guard page 32K
MALLOC metadata 392K
Total: about 665 MByte.
The difference is about 260 MBytes, which is significant but less than the difference according to psutil. But: the psutil difference as calculated by the script is the difference in RSS, not VSIZE (which vmmap shows).
If I change the _mem function to use the VSIZE the before and after values are:
Memory usage: 2390.4 MB
Memory usage: 2846.4 MB
Difference: about 456 MByte, which is still higher than the output of vmmap. 
Note that the same behavior can be seen by a much simpler script:
 print "Large"
 x = list(range(1<<24))
 print _mem()
 del x
 print _mem()
 print
 print "Small"
 x = list(range(1<<23))
 print _mem()
 del x
 print _mem()
(where _mem is the same function as in testiterbug.py).
The output is:
Large
Memory usage: 527.3 MB
Memory usage: 19.3 MB
Small
Memory usage: 330.6 MB
Memory usage: 147.6 MB
With this script is see the same pattern with vmmap: with the "small" list a large amount of memory is in regions of type (MALLOC freed, no zone).
All of this clearly points towards malloc not releasing allocated memory to the system. This is perfectly fine and not a bug in either Python or the system.
msg168120 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012年08月13日 15:36
> The test case finds some leak in 3.3 too, it seems.
3.3 should be much better since it uses mmap() and munmap() to manage the object allocator's arenas (unless this is disabled under OS X for some reason, that is).
Here under Linux:
$ python3.3 testiterbug.py 
3.3.0b1 (default:1d811e1097ed, Jul 29 2012, 20:20:37) 
[GCC 4.5.2]
[row for row in iterit(16777216)]
Memory usage: 7.8 MB
[row for row in iterit(8388608)]
Memory usage: 7.8 MB
msg168124 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2012年08月13日 16:10
> All of this clearly points towards malloc not releasing allocated memory to the system.
> This is perfectly fine and not a bug in either Python or the system.
So it means there's no reliable way to measure the memory consumption of the program.
Sorry for the wrong report, if this is confirmed.
msg168125 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012年08月13日 16:39
> > All of this clearly points towards malloc not releasing allocated memory to the system.
> > This is perfectly fine and not a bug in either Python or the system.
> 
> So it means there's no reliable way to measure the memory consumption of the program.
What it means is that "memory consumption" itself is a bit ill-defined.
"ps", "top" and friends will tell you the amount of memory (physical or
virtual) currently assigned by the OS to the process. It doesn't tell
you whether the memory is "actually" in use by the program.
Note that, in Python 3.3, sys._debugmallocstats() gives you
fined-grained information about the object allocator. This excludes any
blocks bigger than 512 bytes, though, since those are requested directly
using malloc() and free().
msg168441 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2012年08月17日 12:25
Thank you for digging into this. I close the issue.
I discover now that this kind of problem is quite common in the Mac world.
Other references:
http://news.ycombinator.com/item?id=3879194
http://www.markvanda.net/apple/mac-os-x-memory-issues/ 
History
Date User Action Args
2022年04月11日 14:57:34adminsetgithub: 59840
2012年08月17日 12:25:02floxsetstatus: open -> closed
resolution: not a bug
messages: + msg168441
2012年08月13日 16:39:32pitrousetmessages: + msg168125
2012年08月13日 16:10:52floxsetmessages: + msg168124
2012年08月13日 15:36:55pitrousetnosy: + pitrou
messages: + msg168120
2012年08月13日 14:09:53ronaldoussorensetmessages: + msg168108
2012年08月13日 12:56:48r.david.murraysetnosy: + r.david.murray
2012年08月13日 12:23:54ronaldoussorensetmessages: + msg168089
2012年08月13日 12:22:33ronaldoussorensetmessages: + msg168088
2012年08月13日 12:08:43floxsetmessages: + msg168083
2012年08月13日 12:07:10floxsetnosy: + ronaldoussoren, ned.deily, hynek
messages: + msg168082
2012年08月13日 09:25:30floxcreate

AltStyle によって変換されたページ (->オリジナル) /