Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

## {{{ http://code.activestate.com/recipes/577504/ (r3) MIT licensed 

from __future__ import absolute_import, division, print_function 

from sys import getsizeof, stderr 

from itertools import chain 

from collections import deque 

import resource 

try: 

    from reprlib import repr 

except ImportError: 

    pass 

 

 

last_memory_usage = 0 

 

 

def memory_usage(unit='mb'): 

    '''Returns the memory usage of the current process in bytes 

 

    Returns 

    ------- 

    usage 

        Current memory usage. 

    change 

        Change of memory usage since last call. 

    ''' 

    unit = unit.lower() 

    assert unit in ('b', 'kb', 'mb', 'gb') 

    factors = {'b': 1, 

               'kb': 1024, 

               'mb': 1024**2, 

               'gb': 1024**3} 

    global last_memory_usage 

    x = last_memory_usage 

    last_memory_usage = resource.getrusage(resource.RUSAGE_SELF)[2] * 1024 

    return (last_memory_usage / factors[unit], (last_memory_usage - x) / factors[unit]) 

 

 

def print_memory_usage(msg=None, unit='mb'): 

    u = memory_usage(unit) 

    if msg is None: 

        print('Memory usage {0:5.1f} {1} - delta: {2:5.1f} {1}'.format(u[0], unit.upper(), u[1])) 

    else: 

        print('Memory usage {0:5.1f} {1} - delta: {2:5.1f} {1} - {3}'.format(u[0], unit.upper(), u[1], msg)) 

 

 

def total_size(o, handlers={}, verbose=False): 

    """ Returns the approximate memory footprint of an object and all of its contents. 

 

    Automatically finds the contents of the following builtin containers and 

    their subclasses:  tuple, list, deque, dict, set and frozenset. 

    To search other containers, add handlers to iterate over their contents: 

 

        handlers = {SomeContainerClass: iter, 

                    OtherContainerClass: OtherContainerClass.get_elements} 

 

    """ 

    dict_handler = lambda d: chain.from_iterable(d.items()) 

    all_handlers = {tuple: iter, 

                    list: iter, 

                    deque: iter, 

                    dict: dict_handler, 

                    set: iter, 

                    frozenset: iter, 

                    } 

    all_handlers.update(handlers)     # user handlers take precedence 

    seen = set()                      # track which object id's have already been seen 

    default_size = getsizeof(0)       # estimate sizeof object without __sizeof__ 

 

    def sizeof(o): 

        if id(o) in seen:       # do not double count the same object 

            return 0 

        seen.add(id(o)) 

        s = getsizeof(o, default_size) 

 

        if verbose: 

            print(s, type(o), repr(o), file=stderr) 

 

        for typ, handler in all_handlers.items(): 

            if isinstance(o, typ): 

                s += sum(map(sizeof, handler(o))) 

                break 

        return s 

 

    return sizeof(o) 

 

 

##### Example call ##### 

 

if __name__ == '__main__': 

    d = dict(a=1, b=2, c=3, d=[4, 5, 6, 7], e='a string of chars') 

    print(total_size(d, verbose=True)) 

## end of http://code.activestate.com/recipes/577504/ }}}