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