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