[Zope] Zope 2.7.3 Memory Leaks

Tim Peters tim.peters at gmail.com
Sun Dec 5 14:48:07 EST 2004


[Chris McDonough]
> ...
> As I understand it Python has separate memory pools for different
> kinds of objects.  The policy for managing memory deallocation is
> different for each pool.
> 
> I'm no expert about it, I'm just deferring to what I read about it, and
> what I read seems to indicate that releasing the last reference to
> an object doesn't always immediately return the memory
> consumed by that object to the OS.  You probably hit upon a
> case where it does with the above test but I wouldn't assume it's
> indicative of all Python memory deallocation behavior.

It's complicated.  Any request for an object exceeding 256 bytes goes
to the platform malloc().  Python returns such memory via the platform
free().   Whether that in turn "returns the memory to the OS" is
entirely in the hands of the OS and the platform malloc().  It may or
may not.  When it may, whether it does depends on internal malloc()
implementation details, often including the precise history of
malloc() and free() requests.  For example:

    p1 = malloc(50000);
    p2 = malloc(50000);
    p3 = malloc(50000);
    q = malloc(999);
    free(p1);
    free(p2);
    free(p3);

When malloc() works by passing out blocks "low address to high
address", and can only "give back" contiguous high-address chunks to
the OS, then even if malloc() "wants to give memory back" to the OS, a
small object (q) still alive at the highest address passed out so far
will prevent it from returning anything (p1, p2, p3) to the OS.

Objects <= 256 bytes may or may not be obtained via platform malloc().
 Often they're obtained via Python's "small object allocator", which
grabs 256KB at a time from the platform malloc() and carves it up
itself.  These 256KB chunks are currently never given back to the
platform free(), so there's no chance they'll be "returned to the OS"
either.

There are indeed no easy answers here.


More information about the Zope mailing list