Panda3D
memoryUsage.h
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.h
10  * @author drose
11  * @date 2000-05-25
12  */
13 
14 #ifndef MEMORYUSAGE_H
15 #define MEMORYUSAGE_H
16 
17 #include "pandabase.h"
18 #include "typedObject.h"
19 #include "memoryInfo.h"
21 #include "pmap.h"
22 #include "memoryHook.h"
23 
24 class ReferenceCount;
26 
27 /**
28  * This class is used strictly for debugging purposes, specifically for
29  * tracking memory leaks of reference-counted objects: it keeps a record of
30  * every such object currently allocated.
31  *
32  * When compiled with NDEBUG set, this entire class does nothing and compiles
33  * to a stub.
34  */
35 class EXPCL_PANDA_EXPRESS MemoryUsage : public MemoryHook {
36 public:
37  ALWAYS_INLINE static bool get_track_memory_usage();
38 
39  INLINE static void record_pointer(ReferenceCount *ptr);
40  INLINE static void record_pointer(void *ptr, TypeHandle type);
41  INLINE static void update_type(ReferenceCount *ptr, TypeHandle type);
42  INLINE static void update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
43  INLINE static void update_type(void *ptr, TypeHandle type);
44  INLINE static void remove_pointer(ReferenceCount *ptr);
45 
46 protected:
47  // These are not marked public, but they can be accessed via the MemoryHook
48  // base class.
49  virtual void *heap_alloc_single(size_t size);
50  virtual void heap_free_single(void *ptr);
51 
52  virtual void *heap_alloc_array(size_t size);
53  virtual void *heap_realloc_array(void *ptr, size_t size);
54  virtual void heap_free_array(void *ptr);
55 
56  virtual void mark_pointer(void *ptr, size_t orig_size, ReferenceCount *ref_ptr);
57 
58 #if (defined(WIN32_VC) || defined(WIN64_VC)) && defined(_DEBUG)
59  static int win32_malloc_hook(int alloc_type, void *ptr,
60  size_t size, int block_use, long request,
61  const unsigned char *filename, int line);
62 #endif
63 
64 PUBLISHED:
65  INLINE static bool is_tracking();
66  INLINE static bool is_counting();
67  INLINE static size_t get_current_cpp_size();
68  INLINE static size_t get_total_cpp_size();
69 
70  INLINE static size_t get_panda_heap_single_size();
71  INLINE static size_t get_panda_heap_array_size();
72  INLINE static size_t get_panda_heap_overhead();
73  INLINE static size_t get_panda_mmap_size();
74  INLINE static size_t get_external_size();
75  INLINE static size_t get_total_size();
76 
77  INLINE static int get_num_pointers();
78  INLINE static void get_pointers(MemoryUsagePointers &result);
79  INLINE static void get_pointers_of_type(MemoryUsagePointers &result,
80  TypeHandle type);
81  INLINE static void get_pointers_of_age(MemoryUsagePointers &result,
82  double from, double to);
83  INLINE static void get_pointers_with_zero_count(MemoryUsagePointers &result);
84 
85  INLINE static void freeze();
86 
87  INLINE static void show_current_types();
88  INLINE static void show_trend_types();
89  INLINE static void show_current_ages();
90  INLINE static void show_trend_ages();
91 
92 PUBLISHED:
93  MAKE_PROPERTY(tracking, is_tracking);
94  MAKE_PROPERTY(counting, is_counting);
95  MAKE_PROPERTY(current_cpp_size, get_current_cpp_size);
96  MAKE_PROPERTY(total_cpp_size, get_total_cpp_size);
97 
98  MAKE_PROPERTY(panda_heap_single_size, get_panda_heap_single_size);
99  MAKE_PROPERTY(panda_heap_array_size, get_panda_heap_array_size);
100  MAKE_PROPERTY(panda_heap_overhead, get_panda_heap_overhead);
101  MAKE_PROPERTY(panda_mmap_size, get_panda_mmap_size);
102  MAKE_PROPERTY(external_size, get_external_size);
103  MAKE_PROPERTY(total_size, get_total_size);
104 
105 protected:
106  virtual void overflow_heap_size();
107 
108 private:
109  MemoryUsage(const MemoryHook &copy);
110  INLINE static MemoryUsage *get_global_ptr();
111 
112  static void init_memory_usage();
113 
114  void ns_record_pointer(ReferenceCount *ptr);
115  void ns_record_pointer(void *ptr, TypeHandle type);
116  void ns_update_type(void *ptr, TypeHandle type);
117  void ns_update_type(void *ptr, TypedObject *typed_ptr);
118  void ns_remove_pointer(ReferenceCount *ptr);
119 
120  void ns_record_void_pointer(void *ptr, size_t size);
121  void ns_remove_void_pointer(void *ptr);
122 
123  size_t ns_get_total_size();
124  int ns_get_num_pointers();
125  void ns_get_pointers(MemoryUsagePointers &result);
126  void ns_get_pointers_of_type(MemoryUsagePointers &result,
127  TypeHandle type);
128  void ns_get_pointers_of_age(MemoryUsagePointers &result,
129  double from, double to);
130  void ns_get_pointers_with_zero_count(MemoryUsagePointers &result);
131  void ns_freeze();
132 
133  void ns_show_current_types();
134  void ns_show_trend_types();
135  void ns_show_current_ages();
136  void ns_show_trend_ages();
137 
138 #ifdef DO_MEMORY_USAGE
139  void consolidate_void_ptr(MemoryInfo *info);
140  void refresh_info_set();
141 #endif
142 
143  static MemoryUsage *_global_ptr;
144 
145  // We shouldn't use a pmap, since that would be recursive! Actually, it
146  // turns out that it doesn't matter, since somehow the pallocator gets used
147  // even though we don't specify it here, so we have to make special code
148  // that handles the recursion anyway.
149 
150 /*
151  * This table stores up to two entiries for each MemoryInfo object: one for
152  * the void pointer (the pointer to the beginning of the allocated memory
153  * block), and one for the ReferenceCount pointer. For a particular object,
154  * these two pointers may be the same or they may be different. Some objects
155  * may be stored under both pointers, while others may be stored under only
156  * one pointer or the other. We don't store an entry for an object's
157  * TypedObject pointer.
158  */
159  typedef std::map<void *, MemoryInfo *> Table;
160  Table _table;
161 
162  // This table indexes the individual MemoryInfo objects, for unique
163  // iteration.
164  typedef std::set<MemoryInfo *> InfoSet;
165  InfoSet _info_set;
166  bool _info_set_dirty;
167 
168  int _freeze_index;
169  int _count;
170  size_t _current_cpp_size;
171  size_t _total_cpp_size;
172  size_t _total_size;
173 
174  class TypeHistogram {
175  public:
176  void add_info(TypeHandle type, MemoryInfo *info);
177  void show() const;
178  void clear();
179 
180  private:
181  // Cannot use a pmap, since that would be recursive!
182  typedef std::map<TypeHandle, MemoryUsagePointerCounts> Counts;
183  Counts _counts;
184  };
185  TypeHistogram _trend_types;
186 
187  class AgeHistogram {
188  public:
189  AgeHistogram();
190  void add_info(double age, MemoryInfo *info);
191  void show() const;
192  void clear();
193 
194  private:
195  int choose_bucket(double age) const;
196 
197  enum { num_buckets = 5 };
198  MemoryUsagePointerCounts _counts[num_buckets];
199  static double _cutoff[num_buckets];
200  };
201  AgeHistogram _trend_ages;
202 
203 
204  bool _track_memory_usage;
205  bool _startup_track_memory_usage;
206  bool _count_memory_usage;
207  bool _report_memory_usage;
208  double _report_memory_interval;
209  double _last_report_time;
210 
211  static bool _recursion_protect;
212 };
213 
214 #include "memoryUsage.I"
215 
216 #endif
MemoryUsagePointers
This is a list of pointers returned by a MemoryUsage object in response to some query.
Definition: memoryUsagePointers.h:38
memoryHook.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pandabase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ReferenceCount
A base class for all things that want to be reference-counted.
Definition: referenceCount.h:38
MemoryHook::heap_realloc_array
virtual void * heap_realloc_array(void *ptr, size_t size)
Resizes a block of memory previously returned from heap_alloc_array.
Definition: memoryHook.cxx:377
memoryUsage.I
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
MemoryUsage
This class is used strictly for debugging purposes, specifically for tracking memory leaks of referen...
Definition: memoryUsage.h:35
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
pmap.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
MemoryHook::heap_alloc_single
virtual void * heap_alloc_single(size_t size)
Allocates a block of memory from the heap, similar to malloc().
Definition: memoryHook.cxx:250
MemoryHook::heap_alloc_array
virtual void * heap_alloc_array(size_t size)
Allocates a block of memory from the heap, similar to malloc().
Definition: memoryHook.cxx:327
MemoryHook::heap_free_array
virtual void heap_free_array(void *ptr)
Releases a block of memory previously allocated via heap_alloc_array.
Definition: memoryHook.cxx:448
MemoryUsagePointerCounts
This is a supporting class for MemoryUsage.
Definition: memoryUsagePointerCounts.h:27
typedObject.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
MemoryHook
This class provides a wrapper around the various possible malloc schemes Panda might employ.
Definition: memoryHook.h:37
memoryUsagePointerCounts.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
memoryInfo.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
MemoryHook::heap_free_single
virtual void heap_free_single(void *ptr)
Releases a block of memory previously allocated via heap_alloc_single.
Definition: memoryHook.cxx:300
MemoryHook::mark_pointer
virtual void mark_pointer(void *ptr, size_t orig_size, ReferenceCount *ref_ptr)
This special method exists only to provide a callback hook into MemoryUsage.
Definition: memoryHook.cxx:589
TypedObject
This is an abstract class that all classes which use TypeHandle, and also provide virtual functions t...
Definition: typedObject.h:88