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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void heap_free_array(void *ptr)
Releases a block of memory previously allocated via heap_alloc_array.
Definition: memoryHook.cxx:448
virtual void * heap_alloc_single(size_t size)
Allocates a block of memory from the heap, similar to malloc().
Definition: memoryHook.cxx:250
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract class that all classes which use TypeHandle, and also provide virtual functions t...
Definition: typedObject.h:88
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a list of pointers returned by a MemoryUsage object in response to some query.
virtual void heap_free_single(void *ptr)
Releases a block of memory previously allocated via heap_alloc_single.
Definition: memoryHook.cxx:300
This class is used strictly for debugging purposes, specifically for tracking memory leaks of referen...
Definition: memoryUsage.h:35
A base class for all things that want to be reference-counted.
virtual void * heap_alloc_array(size_t size)
Allocates a block of memory from the heap, similar to malloc().
Definition: memoryHook.cxx:327
This class provides a wrapper around the various possible malloc schemes Panda might employ.
Definition: memoryHook.h:37
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
This is a supporting class for MemoryUsage.