Panda3D
Loading...
Searching...
No Matches
memoryUsage.I
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file memoryUsage.I
10 * @author drose
11 * @date 2000-05-25
12 */
13
14/**
15 * Returns true if the user has Configured the variable 'track-memory-usage'
16 * to true, indicating that this class will be in effect. If this returns
17 * false, the user has indicated not to do any of this.
18 */
19ALWAYS_INLINE bool MemoryUsage::
21#ifdef DO_MEMORY_USAGE
22 return get_global_ptr()->_track_memory_usage;
23#else
24 return false;
25#endif
26}
27
28/**
29 * Indicates that the given pointer has been recently allocated.
30 */
31INLINE void MemoryUsage::
33#ifdef DO_MEMORY_USAGE
34 get_global_ptr()->ns_record_pointer(ptr);
35#endif
36}
37
38/**
39 * Indicates that the given pointer has been recently allocated.
40 */
41INLINE void MemoryUsage::
42record_pointer(void *ptr, TypeHandle type) {
43#ifdef DO_MEMORY_USAGE
44 get_global_ptr()->ns_record_pointer(ptr, type);
45#endif
46}
47
48/**
49 * Associates the indicated type with the given pointer. This should be
50 * called by functions (e.g. the constructor) that know more specifically
51 * what type of thing we've got; otherwise, the MemoryUsage database will know
52 * only that it's a "ReferenceCount".
53 */
54INLINE void MemoryUsage::
56#ifdef DO_MEMORY_USAGE
57 get_global_ptr()->ns_update_type((void *)ptr, type);
58#endif
59}
60
61/**
62 * Associates the indicated type with the given pointer. This flavor of
63 * update_type() also passes in the pointer as a TypedObject, and useful for
64 * objects that are, in fact, TypedObjects. Once the MemoryUsage database has
65 * the pointer as a TypedObject it doesn't need any more help.
66 */
67INLINE void MemoryUsage::
68update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
69#ifdef DO_MEMORY_USAGE
70 get_global_ptr()->ns_update_type((void *)ptr, typed_ptr);
71#endif
72}
73
74/**
75 * Associates the indicated type with the given pointer. This should be
76 * called by functions (e.g. the constructor) that know more specifically
77 * what type of thing we've got.
78 */
79INLINE void MemoryUsage::
80update_type(void *ptr, TypeHandle type) {
81#ifdef DO_MEMORY_USAGE
82 get_global_ptr()->ns_update_type(ptr, type);
83#endif
84}
85
86/**
87 * Indicates that the given pointer has been recently freed.
88 */
89INLINE void MemoryUsage::
91#ifdef DO_MEMORY_USAGE
92 get_global_ptr()->ns_remove_pointer(ptr);
93#endif
94}
95
96/**
97 * Returns true if the MemoryUsage object is currently tracking memory (e.g.
98 * track-memory-usage is configured #t).
99 */
100INLINE bool MemoryUsage::
101is_tracking() {
102#ifdef DO_MEMORY_USAGE
103 return get_global_ptr()->_track_memory_usage;
104#else
105 return false;
106#endif
107}
108
109/**
110 * Returns true if the MemoryUsage object is currently at least counting
111 * memory (e.g. this is a Windows debug build), even if it's not fully
112 * tracking it.
113 */
114INLINE bool MemoryUsage::
115is_counting() {
116#ifdef DO_MEMORY_USAGE
117 return get_global_ptr()->_count_memory_usage;
118#else
119 return false;
120#endif
121}
122
123/**
124 * Returns the total number of bytes of allocated memory consumed by C++
125 * objects, not including the memory previously frozen.
126 */
127INLINE size_t MemoryUsage::
129#ifdef DO_MEMORY_USAGE
130 return get_global_ptr()->_current_cpp_size;
131#else
132 return 0;
133#endif
134}
135
136/**
137 * Returns the total number of bytes of allocated memory consumed by C++
138 * objects, including the memory previously frozen.
139 */
140INLINE size_t MemoryUsage::
142#ifdef DO_MEMORY_USAGE
143 return get_global_ptr()->_total_cpp_size;
144#else
145 return 0;
146#endif
147}
148
149/**
150 * Returns the total number of bytes allocated from the heap from code within
151 * Panda, for individual objects.
152 */
153INLINE size_t MemoryUsage::
155#ifdef DO_MEMORY_USAGE
156 return (size_t)AtomicAdjust::get(get_global_ptr()->_total_heap_single_size);
157#else
158 return 0;
159#endif
160}
161
162/**
163 * Returns the total number of bytes allocated from the heap from code within
164 * Panda, for arrays.
165 */
166INLINE size_t MemoryUsage::
168#ifdef DO_MEMORY_USAGE
169 return (size_t)AtomicAdjust::get(get_global_ptr()->_total_heap_array_size);
170#else
171 return 0;
172#endif
173}
174
175/**
176 * Returns the extra bytes allocated from the system that are not immediately
177 * used for holding allocated objects. This can only be determined if
178 * ALTERNATIVE_MALLOC is enabled.
179 */
180INLINE size_t MemoryUsage::
182#if defined(DO_MEMORY_USAGE) && (defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2))
183 MemoryUsage *mu = get_global_ptr();
184 return (size_t)(AtomicAdjust::get(mu->_requested_heap_size) - AtomicAdjust::get(mu->_total_heap_single_size) - AtomicAdjust::get(mu->_total_heap_array_size));
185#else
186 return 0;
187#endif
188}
189
190/**
191 * Returns the total number of bytes allocated from the virtual memory pool
192 * from code within Panda.
193 */
194INLINE size_t MemoryUsage::
196#ifdef DO_MEMORY_USAGE
197 return (size_t)AtomicAdjust::get(get_global_ptr()->_total_mmap_size);
198#else
199 return 0;
200#endif
201}
202
203/**
204 * Returns the total number of bytes of allocated memory in the heap that
205 * Panda didn't seem to be responsible for. This includes a few bytes for
206 * very low-level objects (like ConfigVariables) that cannot use Panda memory
207 * tracking because they are so very low-level.
208 *
209 * This also includes all of the memory that might have been allocated by a
210 * high-level interpreter, like Python.
211 *
212 * This number is only available if Panda is able to hook into the actual heap
213 * callback.
214 */
215INLINE size_t MemoryUsage::
217#ifdef DO_MEMORY_USAGE
218 MemoryUsage *mu = get_global_ptr();
219 if (mu->_count_memory_usage) {
220 // We can only possibly know this with memory counting, which tracks every
221 // malloc call.
222
223#if defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
224 // With alternative malloc, none of the Panda allocated memory shows up in
225 // total_size, so anything there is external.
226 return mu->_total_size;
227#else
228 // Without alternative malloc, the Panda allocated memory is also included
229 // in total_size, so we have to subtract it out.
230 return mu->_total_size - (size_t)mu->_total_heap_single_size - (size_t)mu->_total_heap_array_size;
231#endif
232 } else {
233 return 0;
234 }
235#else
236 return 0;
237#endif
238}
239
240/**
241 * Returns the total size of allocated memory consumed by the process, as
242 * nearly as can be determined.
243 */
244INLINE size_t MemoryUsage::
246#ifdef DO_MEMORY_USAGE
247 MemoryUsage *mu = get_global_ptr();
248 if (mu->_count_memory_usage) {
249 return mu->_total_size + (size_t)mu->_requested_heap_size;
250 } else {
251#if defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
252 return (size_t)mu->_requested_heap_size;
253#else
254 return (size_t)(AtomicAdjust::get(mu->_total_heap_single_size) + AtomicAdjust::get(mu->_total_heap_array_size));
255#endif
256 }
257#else
258 return 0;
259#endif
260}
261
262/**
263 * Returns the number of pointers currently active.
264 */
267#ifdef DO_MEMORY_USAGE
268 return get_global_ptr()->ns_get_num_pointers();
269#else
270 return 0;
271#endif
272}
273
274/**
275 * Fills the indicated MemoryUsagePointers with the set of all pointers
276 * currently active.
277 */
278INLINE void MemoryUsage::
280#ifdef DO_MEMORY_USAGE
281 get_global_ptr()->ns_get_pointers(result);
282#endif
283}
284
285/**
286 * Fills the indicated MemoryUsagePointers with the set of all pointers of the
287 * indicated type currently active.
288 */
289INLINE void MemoryUsage::
291#ifdef DO_MEMORY_USAGE
292 get_global_ptr()->ns_get_pointers_of_type(result, type);
293#endif
294}
295
296/**
297 * Fills the indicated MemoryUsagePointers with the set of all pointers that
298 * were allocated within the range of the indicated number of seconds ago.
299 */
300INLINE void MemoryUsage::
301get_pointers_of_age(MemoryUsagePointers &result, double from, double to) {
302#ifdef DO_MEMORY_USAGE
303 get_global_ptr()->ns_get_pointers_of_age(result, from, to);
304#endif
305}
306
307/**
308 * Fills the indicated MemoryUsagePointers with the set of all currently
309 * active pointers (that is, pointers allocated since the last call to
310 * freeze(), and not yet freed) that have a zero reference count.
311 *
312 * Generally, an undeleted pointer with a zero reference count means its
313 * reference count has never been incremented beyond zero (since once it has
314 * been incremented, the only way it can return to zero would free the
315 * pointer). This may include objects that are allocated statically or on the
316 * stack, which are never intended to be deleted. Or, it might represent a
317 * programmer or compiler error.
318 *
319 * This function has the side-effect of incrementing each of their reference
320 * counts by one, thus preventing them from ever being freed--but since they
321 * hadn't been freed anyway, probably no additional harm is done.
322 */
323INLINE void MemoryUsage::
325#ifdef DO_MEMORY_USAGE
326 get_global_ptr()->ns_get_pointers_with_zero_count(result);
327#endif
328}
329
330/**
331 * 'Freezes' all pointers currently stored so that they are no longer
332 * reported; only newly allocate pointers from this point on will appear in
333 * future information requests. This makes it easier to differentiate between
334 * continuous leaks and one-time memory allocations.
335 */
336INLINE void MemoryUsage::
337freeze() {
338#ifdef DO_MEMORY_USAGE
339 get_global_ptr()->ns_freeze();
340#endif
341}
342
343/**
344 * Shows the breakdown of types of all of the active pointers.
345 */
346INLINE void MemoryUsage::
348#ifdef DO_MEMORY_USAGE
349 get_global_ptr()->ns_show_current_types();
350#endif
351}
352
353/**
354 * Shows the breakdown of types of all of the pointers allocated and freed
355 * since the last call to freeze().
356 */
357INLINE void MemoryUsage::
359#ifdef DO_MEMORY_USAGE
360 get_global_ptr()->ns_show_trend_types();
361#endif
362}
363
364/**
365 * Shows the breakdown of ages of all of the active pointers.
366 */
367INLINE void MemoryUsage::
369#ifdef DO_MEMORY_USAGE
370 get_global_ptr()->ns_show_current_ages();
371#endif
372}
373
374/**
375 * Shows the breakdown of ages of all of the pointers allocated and freed
376 * since the last call to freeze().
377 */
378INLINE void MemoryUsage::
380#ifdef DO_MEMORY_USAGE
381 get_global_ptr()->ns_show_trend_ages();
382#endif
383}
384
385/**
386 * Returns the pointer to the only MemoryUsage object in the world.
387 */
388INLINE MemoryUsage *MemoryUsage::
389get_global_ptr() {
390#ifdef DO_MEMORY_USAGE
391#ifdef __GNUC__
392 // Tell the compiler that this is an unlikely branch.
393 if (__builtin_expect(_global_ptr == nullptr, 0)) {
394#else
395 if (_global_ptr == nullptr) {
396#endif
397 init_memory_usage();
398 }
399
400 return _global_ptr;
401#else
402 return nullptr;
403#endif
404}
static Integer get(const Integer &var)
Atomically retrieves the snapshot value of the indicated variable.
This is a list of pointers returned by a MemoryUsage object in response to some query.
This class is used strictly for debugging purposes, specifically for tracking memory leaks of referen...
Definition memoryUsage.h:35
static void show_current_types()
Shows the breakdown of types of all of the active pointers.
static void get_pointers_of_age(MemoryUsagePointers &result, double from, double to)
Fills the indicated MemoryUsagePointers with the set of all pointers that were allocated within the r...
static void get_pointers(MemoryUsagePointers &result)
Fills the indicated MemoryUsagePointers with the set of all pointers currently active.
get_current_cpp_size
Returns the total number of bytes of allocated memory consumed by C++ objects, not including the memo...
Definition memoryUsage.h:95
static void show_current_ages()
Shows the breakdown of ages of all of the active pointers.
get_external_size
Returns the total number of bytes of allocated memory in the heap that Panda didn't seem to be respon...
get_panda_mmap_size
Returns the total number of bytes allocated from the virtual memory pool from code within Panda.
static void show_trend_types()
Shows the breakdown of types of all of the pointers allocated and freed since the last call to freeze...
get_panda_heap_array_size
Returns the total number of bytes allocated from the heap from code within Panda, for arrays.
Definition memoryUsage.h:99
static void record_pointer(ReferenceCount *ptr)
Indicates that the given pointer has been recently allocated.
Definition memoryUsage.I:32
static void update_type(ReferenceCount *ptr, TypeHandle type)
Associates the indicated type with the given pointer.
Definition memoryUsage.I:55
get_total_size
Returns the total size of allocated memory consumed by the process, as nearly as can be determined.
static void freeze()
'Freezes' all pointers currently stored so that they are no longer reported; only newly allocate poin...
get_panda_heap_single_size
Returns the total number of bytes allocated from the heap from code within Panda, for individual obje...
Definition memoryUsage.h:98
static void get_pointers_with_zero_count(MemoryUsagePointers &result)
Fills the indicated MemoryUsagePointers with the set of all currently active pointers (that is,...
static void get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type)
Fills the indicated MemoryUsagePointers with the set of all pointers of the indicated type currently ...
get_total_cpp_size
Returns the total number of bytes of allocated memory consumed by C++ objects, including the memory p...
Definition memoryUsage.h:96
is_counting
Returns true if the MemoryUsage object is currently at least counting memory (e.g.
Definition memoryUsage.h:94
static int get_num_pointers()
Returns the number of pointers currently active.
static bool get_track_memory_usage()
Returns true if the user has Configured the variable 'track-memory-usage' to true,...
Definition memoryUsage.I:20
static void remove_pointer(ReferenceCount *ptr)
Indicates that the given pointer has been recently freed.
Definition memoryUsage.I:90
get_panda_heap_overhead
Returns the extra bytes allocated from the system that are not immediately used for holding allocated...
static void show_trend_ages()
Shows the breakdown of ages of all of the pointers allocated and freed since the last call to freeze(...
is_tracking
Returns true if the MemoryUsage object is currently tracking memory (e.g.
Definition memoryUsage.h:93
A base class for all things that want to be reference-counted.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
This is an abstract class that all classes which use TypeHandle, and also provide virtual functions t...
Definition typedObject.h:88