1
0

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:
SomberNight
2026-01-20 15:37:15 +00:00
parent 3a8fbabcae
commit 5d41891554

View File

@@ -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")