Message275715
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 |
|
Date |
User |
Action |
Args |
2016-09-10 23:44:30 | eryksun | set | recipients:
+ eryksun, paul.moore, vstinner, tim.golden, python-dev, Okko.Willeboordse, zach.ware, steve.dower |
2016-09-10 23:44:30 | eryksun | set | messageid: <1473551070.28.0.013693993196.issue27932@psf.upfronthosting.co.za> |
2016-09-10 23:44:30 | eryksun | link | issue27932 messages |
2016-09-10 23:44:29 | eryksun | create | |
|