CPython allocates small objects (obmalloc.c, 3.2.3) from 4 KiB pools that it manages in 256 KiB blocks called arenas. Each active pool has a fixed block size of 8 to 256 bytes in increments of 8. For example, a 14-byte object is allocated from the first available pool with a block size of 16 bytes.
There is a potential problem if arenas are allocated on the heap instead of using mmap (this is configured through mallopt M_MMAP_THRESHOLD ), in this the heap cannot be compressed below the highest allocated arena, which will not be released until 1 block in 1 pool is allocated to the object (CPython does not float objects in memory).
Given the above, the next version of your function should probably solve the problem. Replace the return len(explored) with the following 3 lines:
result = len(explored) del i, x, to_explore, current, explored return result + 0
After releasing the containers and all reference objects (releasing the arena back to the system), this returns a new int with the expression result + 0 . A heap cannot be compressed as long as there is a reference to the first result object. In this case, it is automatically freed when the function returns.
If you are testing this interactively without the “plus 0” step, remember that REPL (Read, Eval, Print, Loop) maintains a link to the last result, accessible using the pseudo-variable “ _ ”.
In Python 3.3, this should not be a problem, since the distributor object has been changed to use anonymous mmap for the arena , if any. (The upper limit for the object allocator was also tied to 512 bytes to accommodate 64-bit platforms, but this is immaterial.)
Regarding manual garbage collection, gc.collect() performs a complete assembly of tracked container objects, but also cleans freelists of objects that support built-in types (for example, frames, methods, floats). Python 3.3 has added additional API functions to clear free-list lists ( PyList_ClearFreeList ), dicts ( PyDict_ClearFreeList ) and sets ( PySet_ClearFreeList ). If you prefer to keep your appearance free, use gc.collect(1) .