Skip to content
Snippets Groups Projects
Commit fb23da7a authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

added get_size

parent 74e2dd6c
No related branches found
No related tags found
No related merge requests found
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
* fixed #49 * fixed #49
* fixed #48 * fixed #48
* added get_size
...@@ -8,6 +8,8 @@ be recomputed later. ...@@ -8,6 +8,8 @@ be recomputed later.
Problem is, that they need a trigger to do it. Memory pressure management Problem is, that they need a trigger to do it. Memory pressure management
from Satella solves that problem. from Satella solves that problem.
.. autofunction:: satella.instrumentation.memory.get_size
Defining severity levels Defining severity levels
------------------------ ------------------------
......
__version__ = '2.17.19a3' __version__ = '2.17.19'
...@@ -3,8 +3,9 @@ from .conditions import Any, All, GlobalRelativeValue, GlobalAbsoluteValue, Loca ...@@ -3,8 +3,9 @@ from .conditions import Any, All, GlobalRelativeValue, GlobalAbsoluteValue, Loca
from .default import install_force_gc_collect from .default import install_force_gc_collect
from .memthread import MemoryPressureManager from .memthread import MemoryPressureManager
from .dump_frames_on import dump_memory_on, install_dump_memory_on from .dump_frames_on import dump_memory_on, install_dump_memory_on
from .get_object_size import get_size
__all__ = ['Any', 'All', 'MemoryPressureManager', 'GlobalAbsoluteValue', __all__ = ['Any', 'All', 'MemoryPressureManager', 'GlobalAbsoluteValue',
'GB', 'GlobalRelativeValue', 'LocalRelativeValue', 'LocalAbsoluteValue', 'MB', 'KB', 'GB', 'GlobalRelativeValue', 'LocalRelativeValue', 'LocalAbsoluteValue', 'MB', 'KB',
'CustomCondition', 'Not', 'install_force_gc_collect', 'CustomCondition', 'Not', 'install_force_gc_collect',
'dump_memory_on', 'install_dump_memory_on'] 'dump_memory_on', 'install_dump_memory_on', 'get_size']
import sys
# shamelessly stolen from
# https://goshippo.com/blog/measure-real-size-any-python-object/
def get_size(obj, seen=None) -> int:
"""
Recursively finds size of objects
:param obj: object to measure
:return: size in bytes of the object and all of it's subcomponents
"""
size = sys.getsizeof(obj)
if seen is None:
seen = set()
obj_id = id(obj)
if obj_id in seen:
return 0
# Important mark as seen *before* entering recursion to gracefully handle
# self-referential objects
seen.add(obj_id)
if isinstance(obj, dict):
size += sum(get_size(v, seen) for v in obj.values())
size += sum(get_size(k, seen) for k in obj.keys())
elif hasattr(obj, '__dict__'):
size += get_size(obj.__dict__, seen)
elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes, bytearray)):
size += sum(get_size(i, seen) for i in obj)
return size
...@@ -5,7 +5,7 @@ import sys ...@@ -5,7 +5,7 @@ import sys
from satella.instrumentation import install_dump_frames_on from satella.instrumentation import install_dump_frames_on
from satella.instrumentation.memory import MemoryPressureManager, CustomCondition, All, Any, \ from satella.instrumentation.memory import MemoryPressureManager, CustomCondition, All, Any, \
dump_memory_on dump_memory_on, get_size
import time import time
import unittest import unittest
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -27,6 +27,10 @@ class TestMemory(unittest.TestCase): ...@@ -27,6 +27,10 @@ class TestMemory(unittest.TestCase):
install_dump_frames_on(signal.SIGUSR1) install_dump_frames_on(signal.SIGUSR1)
os.kill(os.getpid(), signal.SIGUSR1) os.kill(os.getpid(), signal.SIGUSR1)
def test_get_size(self):
a = 'a' * 1024
self.assertGreaterEqual(get_size(a), 1024)
def test_dump_memory(self): def test_dump_memory(self):
dump_memory_on() dump_memory_on()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment