utils/memory_leak: factor out count_objects_in_memory
and use weakrefs, to properly allow using this to test garbage collection
This commit is contained in:
@@ -2,10 +2,29 @@ from collections import defaultdict
|
|||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
from typing import Sequence, Mapping, TypeVar, Optional
|
||||||
|
import weakref
|
||||||
|
|
||||||
from electrum.util import ThreadJob
|
from electrum.util import ThreadJob
|
||||||
|
|
||||||
|
|
||||||
|
_U = TypeVar('_U')
|
||||||
|
|
||||||
|
def count_objects_in_memory(mclasses: Sequence[type[_U]]) -> Mapping[type[_U], Sequence[weakref.ref[_U]]]:
|
||||||
|
import gc
|
||||||
|
gc.collect()
|
||||||
|
objmap = defaultdict(list)
|
||||||
|
for obj in gc.get_objects():
|
||||||
|
for class_ in mclasses:
|
||||||
|
try:
|
||||||
|
_isinstance = isinstance(obj, class_)
|
||||||
|
except AttributeError:
|
||||||
|
_isinstance = False
|
||||||
|
if _isinstance:
|
||||||
|
objmap[class_].append(weakref.ref(obj))
|
||||||
|
return objmap
|
||||||
|
|
||||||
|
|
||||||
class DebugMem(ThreadJob):
|
class DebugMem(ThreadJob):
|
||||||
'''A handy class for debugging GC memory leaks
|
'''A handy class for debugging GC memory leaks
|
||||||
|
|
||||||
@@ -21,18 +40,8 @@ class DebugMem(ThreadJob):
|
|||||||
self.interval = interval
|
self.interval = interval
|
||||||
|
|
||||||
def mem_stats(self):
|
def mem_stats(self):
|
||||||
import gc
|
|
||||||
self.logger.info("Start memscan")
|
self.logger.info("Start memscan")
|
||||||
gc.collect()
|
objmap = count_objects_in_memory(self.classes)
|
||||||
objmap = defaultdict(list)
|
|
||||||
for obj in gc.get_objects():
|
|
||||||
for class_ in self.classes:
|
|
||||||
try:
|
|
||||||
_isinstance = isinstance(obj, class_)
|
|
||||||
except AttributeError:
|
|
||||||
_isinstance = False
|
|
||||||
if _isinstance:
|
|
||||||
objmap[class_].append(obj)
|
|
||||||
for class_, objs in objmap.items():
|
for class_, objs in objmap.items():
|
||||||
self.logger.info(f"{class_.__name__}: {len(objs)}")
|
self.logger.info(f"{class_.__name__}: {len(objs)}")
|
||||||
self.logger.info("Finish memscan")
|
self.logger.info("Finish memscan")
|
||||||
|
|||||||
Reference in New Issue
Block a user