0
# Growth Analysis and Monitoring
1
2
Tools for tracking object creation and growth patterns over time. These functions are essential for identifying memory leaks, monitoring memory usage trends, and understanding which parts of your code are creating objects.
3
4
## Capabilities
5
6
### Peak Object Growth Tracking
7
8
Track increases in peak object counts since the last measurement, helping identify gradual memory leaks.
9
10
```python { .api }
11
def growth(limit=10, peak_stats={}, shortnames=True, filter=None):
12
"""
13
Count the increase in peak object counts since last call.
14
15
Args:
16
limit (int): Maximum number of deltas to return; None to see all
17
peak_stats (dict): Dictionary from type names to previously seen peak counts; usually managed automatically
18
shortnames (bool): If True, use short class names; if False, use fully qualified names
19
filter (callable, optional): Function taking object and returning bool; objects returning False are ignored
20
21
Returns:
22
list: List of (type_name, total_count, increase_delta) tuples, descending by increase_delta
23
24
Note:
25
Calls gc.collect() automatically and updates peak_stats with new peak values.
26
"""
27
```
28
29
Usage examples:
30
31
```python
32
import objgraph
33
34
# Initial measurement - establishes baseline
35
objgraph.growth()
36
37
# ... run some code that might create objects ...
38
39
# Check for growth since last call
40
growth_data = objgraph.growth()
41
for type_name, total, delta in growth_data:
42
print(f"{type_name}: {total} total ({delta:+d} since last check)")
43
44
# Use persistent peak stats across calls
45
peak_stats = {}
46
initial_growth = objgraph.growth(peak_stats=peak_stats)
47
# ... more code ...
48
later_growth = objgraph.growth(peak_stats=peak_stats)
49
50
# Get unlimited results
51
all_growth = objgraph.growth(limit=None)
52
```
53
54
### Growth Display
55
56
Print formatted growth tables showing object count increases.
57
58
```python { .api }
59
def show_growth(limit=10, peak_stats=None, shortnames=True, file=None, filter=None):
60
"""
61
Show the increase in peak object counts since last call.
62
63
Args:
64
limit (int): Maximum number of entries to show
65
peak_stats (dict, optional): Peak stats dictionary; if None, uses internal state
66
shortnames (bool): If True, use short class names; if False, use fully qualified names
67
file (file-like, optional): Output destination; defaults to sys.stdout
68
filter (callable, optional): Function taking object and returning bool; objects returning False are ignored
69
70
Returns:
71
None: Prints formatted output
72
"""
73
```
74
75
Usage examples:
76
77
```python
78
import objgraph
79
import sys
80
81
# Basic growth monitoring workflow
82
objgraph.show_growth() # Establish baseline
83
# ... run some code ...
84
objgraph.show_growth() # Show changes
85
86
# Custom file output
87
with open('growth_log.txt', 'w') as f:
88
objgraph.show_growth(file=f)
89
90
# Use external peak stats for more control
91
peak_stats = {}
92
objgraph.show_growth(peak_stats=peak_stats)
93
# ... later ...
94
objgraph.show_growth(peak_stats=peak_stats)
95
96
# Show fully qualified names
97
objgraph.show_growth(shortnames=False)
98
99
# Filter to specific object types
100
def is_my_class(obj):
101
return type(obj).__name__.startswith('My')
102
103
objgraph.show_growth(filter=is_my_class)
104
```
105
106
Example output:
107
```
108
wrapper_descriptor 970 +14
109
tuple 12282 +10
110
dict 1922 +7
111
list 1433 +3
112
```
113
114
### New Object ID Tracking
115
116
Track individual object creation by monitoring object IDs, providing detailed information about newly created objects.
117
118
```python { .api }
119
def get_new_ids(skip_update=False, limit=10, sortby='deltas', shortnames=None, file=None, _state={}):
120
"""
121
Find and display new objects allocated since last call.
122
123
Args:
124
skip_update (bool): If True, returns previous results without updating internal state
125
limit (int): Maximum number of rows to print; 0 to suppress printing; None to print everything
126
sortby (str): Column to sort by ('old', 'current', 'new', 'deltas')
127
shortnames (bool, optional): Use short class names; if None, remembers previous setting (default True)
128
file (file-like, optional): Output destination; defaults to sys.stdout
129
_state (dict): Internal state storage; do not pass manually
130
131
Returns:
132
dict: Mapping from type names to sets of object IDs created since last call
133
134
Note:
135
Calls gc.collect() automatically. Use with at_addrs() to get actual objects from IDs.
136
"""
137
```
138
139
Usage examples:
140
141
```python
142
import objgraph
143
144
# Establish baseline
145
objgraph.get_new_ids(limit=0) # Don't print, just establish state
146
147
# ... create some objects ...
148
a = [1, 2, 3]
149
b = {'key': 'value'}
150
c = [4, 5, 6]
151
152
# Get new object IDs and print summary
153
new_ids = objgraph.get_new_ids()
154
155
# Get actual objects from IDs
156
new_lists = objgraph.at_addrs(new_ids.get('list', set()))
157
print(f"New lists created: {len(new_lists)}")
158
print(f"Our list 'a' is in new lists: {a in new_lists}")
159
160
# Skip update to get previous results again
161
same_ids = objgraph.get_new_ids(skip_update=True)
162
163
# Sort by different columns
164
objgraph.get_new_ids(sortby='current') # Sort by current count
165
objgraph.get_new_ids(sortby='new') # Sort by new objects count
166
objgraph.get_new_ids(sortby='old') # Sort by old count
167
168
# Unlimited output
169
all_new_ids = objgraph.get_new_ids(limit=None)
170
171
# Fully qualified names
172
objgraph.get_new_ids(shortnames=False)
173
```
174
175
Example output:
176
```
177
======================================================================
178
Type Old_ids Current_ids New_ids Count_Deltas
179
======================================================================
180
list 324 326 +3 +2
181
dict 1125 1125 +0 +0
182
wrapper_descriptor 1001 1001 +0 +0
183
======================================================================
184
```
185
186
## Common Workflows
187
188
### Memory Leak Detection
189
190
```python
191
import objgraph
192
193
# Establish baseline
194
objgraph.show_growth()
195
196
# Run your code that might leak memory
197
for i in range(1000):
198
# some_potentially_leaky_operation()
199
pass
200
201
# Check for consistent growth
202
objgraph.show_growth()
203
204
# Get specific objects for investigation
205
new_ids = objgraph.get_new_ids()
206
if 'MyClass' in new_ids:
207
leaked_objects = objgraph.at_addrs(new_ids['MyClass'])
208
# Investigate what's keeping these objects alive
209
objgraph.show_backrefs(leaked_objects[:5])
210
```
211
212
### Periodic Monitoring
213
214
```python
215
import objgraph
216
import time
217
218
peak_stats = {}
219
220
while True:
221
objgraph.show_growth(peak_stats=peak_stats)
222
time.sleep(60) # Check every minute
223
```