Message275715
| Author |
eryksun |
| Recipients |
Okko.Willeboordse, eryksun, paul.moore, python-dev, steve.dower, tim.golden, vstinner, zach.ware |
| Date |
2016年09月10日.23:44:29 |
| SpamBayes Score |
-1.0 |
| Marked as misclassified |
Yes |
| Message-id |
<1473551070.28.0.013693993196.issue27932@psf.upfronthosting.co.za> |
| In-reply-to |
| Content |
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 |
|