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