util: move DebugMem from util to utils/memory_leak.py
What changed, and why it matters
This commit simply moves an internal developer-only debugging helper class (DebugMem) from one file to another. It is not a security fix and does not change any user-facing behavior. The code is used only for diagnosing memory leaks during development.
No security action needed. This is a code organization/refactoring change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch relocates the DebugMem class from electrum/util.py to a new file electrum/utils/memory_leak.py. The class implementation is essentially unchanged, with only minor additions: a docstring and an import of defaultdict and time in the new file. DebugMem is a diagnostic tool that periodically scans the Python garbage collector’s object list and logs counts of specified classes. It is not invoked in normal operation and has no security-relevant effect.
Changed components
electrum/util.pyelectrum/utils/memory_leak.pyInspect captured patch +41 / −29
diff --git a/electrum/util.py b/electrum/util.py
index 0bad5f5..93f7546 100644
--- a/electrum/util.py
+++ b/electrum/util.py
@@ -350,35 +350,6 @@ class ThreadJob(Logger):
"""Called periodically from the thread"""
pass
-class DebugMem(ThreadJob):
- '''A handy class for debugging GC memory leaks'''
- def __init__(self, classes, interval=30):
- ThreadJob.__init__(self)
- self.next_time = 0
- self.classes = classes
- self.interval = interval
-
- def mem_stats(self):
- import gc
- self.logger.info("Start memscan")
- gc.collect()
- 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():
- self.logger.info(f"{class_.__name__}: {len(objs)}")
- self.logger.info("Finish memscan")
-
- def run(self):
- if time.time() > self.next_time:
- self.mem_stats()
- self.next_time = time.time() + self.interval
class DaemonThread(threading.Thread, Logger):
""" daemon thread that terminates cleanly """
diff --git a/electrum/utils/memory_leak.py b/electrum/utils/memory_leak.py
new file mode 100644
index 0000000..8b276d5
--- /dev/null
+++ b/electrum/utils/memory_leak.py
@@ -0,0 +1,41 @@
+from collections import defaultdict
+import time
+
+from electrum.util import ThreadJob
+
+
+class DebugMem(ThreadJob):
+ '''A handy class for debugging GC memory leaks
+
+ In console:
+ >>> from electrum.utils.memory_leak import DebugMem
+ >>> from electrum.wallet import Abstract_Wallet
+ >>> plugins.add_jobs([DebugMem([Abstract_Wallet,], interval=5)])
+ '''
+ def __init__(self, classes, interval=30):
+ ThreadJob.__init__(self)
+ self.next_time = 0
+ self.classes = classes
+ self.interval = interval
+
+ def mem_stats(self):
+ import gc
+ self.logger.info("Start memscan")
+ gc.collect()
+ 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():
+ self.logger.info(f"{class_.__name__}: {len(objs)}")
+ self.logger.info("Finish memscan")
+
+ def run(self):
+ if time.time() > self.next_time:
+ self.mem_stats()
+ self.next_time = time.time() + self.interval
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.