Eryk Sun added the comment:

The leak is due the pointer-type cache that ctypes.POINTER uses. The type the 
pointer refers to is used as the key. In this case, VS_FIXEDFILEINFO is created 
each time win32_ver is called, so the pointer-type cache grows without bound. 
Example leak:

    >>> import psutil, platform
    >>> proc = psutil.Process()
    >>> proc.memory_info().rss
    14704640
    >>> for i in range(10000):
    ...     v = platform.win32_ver()
    ...
    >>> proc.memory_info().rss
    92704768
    >>> for i in range(10000):
    ...     v = platform.win32_ver()
    ...
    >>> proc.memory_info().rss
    168861696

Clearing the cache followed by a collect() reclaims the leaked memory for the 
most part:

    >>> import gc, ctypes
    >>> gc.collect()
    333
    >>> proc.memory_info().rss
    168849408
    >>> ctypes._pointer_type_cache.clear()
    >>> gc.collect()
    740000
    >>> proc.memory_info().rss
    20303872

It's a moot point, since Steve plans to re-implement this check in C, but the 
minimal change to fix this leak is to bypass the pointer-type cache by manually 
subclassing ctypes._Pointer:

    class PVS_FIXEDFILEINFO(_Pointer):
        _type_ = VS_FIXEDFILEINFO

    pvi = PVS_FIXEDFILEINFO()

There's no more leak after this change:

    >>> import psutil, platform
    >>> proc = psutil.Process()
    >>> proc.memory_info().rss
    15450112
    >>> for i in range(10000):
    ...     v = platform.win32_ver()
    ...
    >>> proc.memory_info().rss
    16592896
    >>> for i in range(10000):
    ...     v = platform.win32_ver()
    ...
    >>> proc.memory_info().rss
    16601088

----------
nosy: +eryksun

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue27932>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to