示例#1
0
    def __init__(self,
                 excluded_obj: Optional[Union[object, str]] = None) -> None:
        self.sizer = asizeof.Asizer()
        self.excluded = []

        if excluded_obj is not None:
            self.set_excluded_asizer(excluded_obj)
示例#2
0
    def create_snapshot(self, description='', compute_total=False):
        """
        Collect current per instance statistics and saves total amount of
        memory associated with the Python process.

        If `compute_total` is `True`, the total consumption of all objects
        known to *asizeof* is computed. The latter might be very slow if many
        objects are mapped into memory at the time the snapshot is taken.
        Therefore, `compute_total` is set to `False` by default.

        The overhead of the `ClassTracker` structure is also computed.

        Snapshots can be taken asynchronously. The function is protected with a
        lock to prevent race conditions.
        """

        try:
            # TODO: It is not clear what happens when memory is allocated or
            # released while this function is executed but it will likely lead
            # to inconsistencies. Either pause all other threads or don't size
            # individual objects in asynchronous mode.
            self.snapshot_lock.acquire()

            timestamp = _get_time()

            sizer = asizeof.Asizer()
            objs = [tobj.ref() for tobj in list(self.objects.values())]
            sizer.exclude_refs(*objs)

            # The objects need to be sized in a deterministic order. Sort the
            # objects by its creation date which should at least work for
            # non-parallel execution. The "proper" fix would be to handle
            # shared data separately.
            tracked_objects = list(self.objects.values())
            tracked_objects.sort(key=lambda x: x.birth)
            for tobj in tracked_objects:
                tobj.track_size(timestamp, sizer)

            snapshot = Snapshot()

            snapshot.timestamp = timestamp
            snapshot.tracked_total = sizer.total
            if compute_total:
                snapshot.asizeof_total = asizeof.asizeof(all=True, code=True)
            snapshot.system_total = pympler.process.ProcessMemoryInfo()
            snapshot.desc = str(description)

            # Compute overhead of all structures, use sizer to exclude tracked
            # objects(!)
            snapshot.overhead = 0
            if snapshot.tracked_total:
                snapshot.overhead = sizer.asizeof(self)
                if snapshot.asizeof_total:
                    snapshot.asizeof_total -= snapshot.overhead

            self.snapshots.append(snapshot)

        finally:
            self.snapshot_lock.release()
示例#3
0
def track_object(obj, msg=None):
    """Track sizeof obj. Only when testing w/ pympler installed"""
    if not _testing or not asizeof:
        return

    sizer = asizeof.Asizer()
    sizer.exclude_types(_excludes)
    tracked_objects[id(obj)].append(
        (time.time(), obj, sizer.asizeof(obj) / 1024.0, msg)
    )
示例#4
0
 def test_asizer(self):
     '''Test Asizer properties.
     '''
     sizer = asizeof.Asizer()
     obj = 'unladen swallow'
     mutable = [obj]
     sizer.asizeof(obj)
     self.assertEqual(sizer.total, asizeof.asizeof(obj))
     sizer.asizeof(mutable, mutable)
     self.assertEqual(sizer.duplicate, 1)
     self.assertEqual(sizer.total, asizeof.asizeof(obj, mutable))
示例#5
0
 def test_asizer_limit(self):
     '''Test limit setting for Asizer.
     '''
     objs = [Foo(42), ThinFoo("spam"), OldFoo(67)]
     sizer = [asizeof.Asizer() for _ in range(4)]
     for limit, asizer in enumerate(sizer):
         asizer.asizeof(objs, limit=limit)
     limit_sizes = [asizer.total for asizer in sizer]
     self.assertTrue(limit_sizes[0] < limit_sizes[1], limit_sizes)
     self.assertTrue(limit_sizes[1] < limit_sizes[2], limit_sizes)
     self.assertTrue(limit_sizes[2] < limit_sizes[3], limit_sizes)
示例#6
0
def track_object(obj, msg=None):
    if not asizeof:
        return

    # Only track if testing
    sizer = asizeof.Asizer()
    sizer.exclude_types(_excludes)
    if not _testing:
        return

    tracked_objects[id(obj)].append(
        (time.time(), obj, sizer.asizeof(obj) / 1024.0, msg))
示例#7
0
 def test_asized(self):
     '''Test asizeof.asized()
     '''
     self.assertEqual(list(asizeof.asized(detail=2)), [])
     self.assertRaises(KeyError, asizeof.asized, **{'all': True})
     sized = asizeof.asized(Foo(42), detail=2)
     self.assert_("Foo" in sized.name, sized.name)
     refs = [ref for ref in sized.refs if ref.name == '__dict__']
     self.assertEqual(len(refs), 1)
     refs = [ref for ref in refs[0].refs if ref.name == '[V] data: 42']
     self.assertEqual(len(refs), 1, refs)
     i = 42
     self.assertEqual(refs[0].size, asizeof.asizeof(i), refs[0].size)
     # Size multiple objects
     sizer = asizeof.Asizer()
     sized_objs = sizer.asized(Foo(3), Foo(4), detail=2)
     self.assertEqual(len(sized_objs), 2)
示例#8
0
    def test_asizesof(self):
        '''Test asizeof.asizesof()
        '''
        self.assertEqual(list(asizeof.asizesof()), [])
        self.assertRaises(KeyError, asizeof.asizesof, **{'all': True})

        objs = [Foo(42), ThinFoo("spam"), OldFoo(67)]
        sizes = list(asizeof.asizesof(*objs))
        objs.reverse()
        rsizes = list(asizeof.asizesof(*objs))
        self.assertEqual(len(sizes), 3)
        rsizes.reverse()
        self.assertEqual(sizes, rsizes, (sizes, rsizes))
        objs.reverse()
        isizes = [asizeof.asizeof(obj) for obj in objs]
        self.assertEqual(sizes, isizes)
        sizer = asizeof.Asizer()
        asizer_sizes = sizer.asizesof(*objs)
        self.assertEqual(list(asizer_sizes), sizes)
        code_sizes = sizer.asizesof(*objs, **dict(code=True))
        self.failIfEqual(list(code_sizes), sizes)
示例#9
0
 def test_exclude_types(self):
     '''Test Asizer.exclude_types().
     '''
     sizer = asizeof.Asizer()
     sizer.exclude_types(Foo)
     self.assertEqual(sizer.asizeof(Foo('ignored')), 0)