00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef MEMORYUSAGE_H
00016 #define MEMORYUSAGE_H
00017
00018 #include "pandabase.h"
00019
00020 #ifdef DO_MEMORY_USAGE
00021
00022 #include "typedObject.h"
00023 #include "memoryInfo.h"
00024 #include "memoryUsagePointerCounts.h"
00025 #include "pmap.h"
00026 #include "memoryHook.h"
00027
00028 class ReferenceCount;
00029 class MemoryUsagePointers;
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 class EXPCL_PANDAEXPRESS MemoryUsage : public MemoryHook {
00042 public:
00043 INLINE static bool get_track_memory_usage();
00044
00045 INLINE static void record_pointer(ReferenceCount *ptr);
00046 INLINE static void update_type(ReferenceCount *ptr, TypeHandle type);
00047 INLINE static void update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
00048 INLINE static void remove_pointer(ReferenceCount *ptr);
00049
00050 public:
00051 virtual void *heap_alloc_single(size_t size);
00052 virtual void heap_free_single(void *ptr);
00053
00054 virtual void *heap_alloc_array(size_t size);
00055 virtual void *heap_realloc_array(void *ptr, size_t size);
00056 virtual void heap_free_array(void *ptr);
00057
00058 virtual void mark_pointer(void *ptr, size_t orig_size, ReferenceCount *ref_ptr);
00059
00060 #if (defined(WIN32_VC) || defined(WIN64_VC)) && defined(_DEBUG)
00061 static int win32_malloc_hook(int alloc_type, void *ptr,
00062 size_t size, int block_use, long request,
00063 const unsigned char *filename, int line);
00064 #endif
00065
00066 PUBLISHED:
00067 INLINE static bool is_tracking();
00068 INLINE static bool is_counting();
00069 INLINE static size_t get_current_cpp_size();
00070 INLINE static size_t get_total_cpp_size();
00071
00072 INLINE static size_t get_panda_heap_single_size();
00073 INLINE static size_t get_panda_heap_array_size();
00074 INLINE static size_t get_panda_heap_overhead();
00075 INLINE static size_t get_panda_mmap_size();
00076 INLINE static size_t get_external_size();
00077 INLINE static size_t get_total_size();
00078
00079 INLINE static int get_num_pointers();
00080 INLINE static void get_pointers(MemoryUsagePointers &result);
00081 INLINE static void get_pointers_of_type(MemoryUsagePointers &result,
00082 TypeHandle type);
00083 INLINE static void get_pointers_of_age(MemoryUsagePointers &result,
00084 double from, double to);
00085 INLINE static void get_pointers_with_zero_count(MemoryUsagePointers &result);
00086
00087 INLINE static void freeze();
00088
00089 INLINE static void show_current_types();
00090 INLINE static void show_trend_types();
00091 INLINE static void show_current_ages();
00092 INLINE static void show_trend_ages();
00093
00094 protected:
00095 virtual void overflow_heap_size();
00096
00097 private:
00098 MemoryUsage(const MemoryHook ©);
00099 static MemoryUsage *get_global_ptr();
00100
00101 void ns_record_pointer(ReferenceCount *ptr);
00102 void ns_update_type(ReferenceCount *ptr, TypeHandle type);
00103 void ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
00104 void ns_remove_pointer(ReferenceCount *ptr);
00105
00106 void ns_record_void_pointer(void *ptr, size_t size);
00107 void ns_remove_void_pointer(void *ptr);
00108
00109 size_t ns_get_total_size();
00110 int ns_get_num_pointers();
00111 void ns_get_pointers(MemoryUsagePointers &result);
00112 void ns_get_pointers_of_type(MemoryUsagePointers &result,
00113 TypeHandle type);
00114 void ns_get_pointers_of_age(MemoryUsagePointers &result,
00115 double from, double to);
00116 void ns_get_pointers_with_zero_count(MemoryUsagePointers &result);
00117 void ns_freeze();
00118
00119 void ns_show_current_types();
00120 void ns_show_trend_types();
00121 void ns_show_current_ages();
00122 void ns_show_trend_ages();
00123
00124 void consolidate_void_ptr(MemoryInfo *info);
00125 void refresh_info_set();
00126
00127 static MemoryUsage *_global_ptr;
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 typedef map<void *, MemoryInfo *> Table;
00143 Table _table;
00144
00145
00146
00147 typedef set<MemoryInfo *> InfoSet;
00148 InfoSet _info_set;
00149 bool _info_set_dirty;
00150
00151 int _freeze_index;
00152 int _count;
00153 size_t _current_cpp_size;
00154 size_t _total_cpp_size;
00155 size_t _total_size;
00156
00157 class TypeHistogram {
00158 public:
00159 void add_info(TypeHandle type, MemoryInfo *info);
00160 void show() const;
00161 void clear();
00162
00163 private:
00164
00165 typedef map<TypeHandle, MemoryUsagePointerCounts> Counts;
00166 Counts _counts;
00167 };
00168 TypeHistogram _trend_types;
00169
00170 class AgeHistogram {
00171 public:
00172 AgeHistogram();
00173 void add_info(double age, MemoryInfo *info);
00174 void show() const;
00175 void clear();
00176
00177 private:
00178 int choose_bucket(double age) const;
00179
00180 enum { num_buckets = 5 };
00181 MemoryUsagePointerCounts _counts[num_buckets];
00182 static double _cutoff[num_buckets];
00183 };
00184 AgeHistogram _trend_ages;
00185
00186
00187 bool _track_memory_usage;
00188 bool _startup_track_memory_usage;
00189 bool _count_memory_usage;
00190 bool _report_memory_usage;
00191 double _report_memory_interval;
00192 double _last_report_time;
00193
00194 static bool _recursion_protect;
00195 };
00196
00197 #include "memoryUsage.I"
00198
00199 #endif // DO_MEMORY_USAGE
00200
00201 #endif
00202