Panda3D
Loading...
Searching...
No Matches
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
24class 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 */
35class EXPCL_PANDA_EXPRESS MemoryUsage : public MemoryHook {
36public:
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
46protected:
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
64PUBLISHED:
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
92PUBLISHED:
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
105protected:
106 virtual void overflow_heap_size();
107
108private:
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
This class provides a wrapper around the various possible malloc schemes Panda might employ.
Definition memoryHook.h:37
virtual void * heap_alloc_array(size_t size)
Allocates a block of memory from the heap, similar to malloc().
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.
virtual void heap_free_single(void *ptr)
Releases a block of memory previously allocated via heap_alloc_single.
virtual void * heap_realloc_array(void *ptr, size_t size)
Resizes a block of memory previously returned from heap_alloc_array.
This is a supporting class for MemoryUsage.
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
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.