1 // Copyright (c) 2012, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // --- 31 // Author: Sanjay Ghemawat <opensource (at) google.com> 32 // 33 // Extra extensions exported by some malloc implementations. These 34 // extensions are accessed through a virtual base class so an 35 // application can link against a malloc that does not implement these 36 // extensions, and it will get default versions that do nothing. 37 // 38 // NOTE FOR C USERS: If you wish to use this functionality from within 39 // a C program, see malloc_extension_c.h. 40 41 #ifndef BASE_MALLOC_EXTENSION_H_ 42 #define BASE_MALLOC_EXTENSION_H_ 43 44 #include <stddef.h> 45 // I can't #include config.h in this public API file, but I should 46 // really use configure (and make malloc_extension.h a .in file) to 47 // figure out if the system has stdint.h or not. But I'm lazy, so 48 // for now I'm assuming it's a problem only with MSVC. 49 #ifndef _MSC_VER 50 #include <stdint.h> 51 #endif 52 #include <string> 53 #include <vector> 54 55 // Annoying stuff for windows -- makes sure clients can import these functions 56 #ifndef PERFTOOLS_DLL_DECL 57 # ifdef _WIN32 58 # define PERFTOOLS_DLL_DECL __declspec(dllimport) 59 # else 60 # define PERFTOOLS_DLL_DECL 61 # endif 62 #endif 63 64 static const int kMallocHistogramSize = 64; 65 66 // One day, we could support other types of writers (perhaps for C?) 67 typedef std::string MallocExtensionWriter; 68 69 namespace base { 70 struct MallocRange; 71 } 72 73 // Interface to a pluggable system allocator. 74 class SysAllocator { 75 public: 76 SysAllocator() { 77 } 78 virtual ~SysAllocator(); 79 80 // Allocates "size"-byte of memory from system aligned with "alignment". 81 // Returns NULL if failed. Otherwise, the returned pointer p up to and 82 // including (p + actual_size -1) have been allocated. 83 virtual void* Alloc(size_t size, size_t *actual_size, size_t alignment) = 0; 84 }; 85 86 // The default implementations of the following routines do nothing. 87 // All implementations should be thread-safe; the current one 88 // (TCMallocImplementation) is. 89 class PERFTOOLS_DLL_DECL MallocExtension { 90 public: 91 virtual ~MallocExtension(); 92 93 // Call this very early in the program execution -- say, in a global 94 // constructor -- to set up parameters and state needed by all 95 // instrumented malloc implemenatations. One example: this routine 96 // sets environemnt variables to tell STL to use libc's malloc() 97 // instead of doing its own memory management. This is safe to call 98 // multiple times, as long as each time is before threads start up. 99 static void Initialize(); 100 101 // See "verify_memory.h" to see what these routines do 102 virtual bool VerifyAllMemory(); 103 virtual bool VerifyNewMemory(const void* p); 104 virtual bool VerifyArrayNewMemory(const void* p); 105 virtual bool VerifyMallocMemory(const void* p); 106 virtual bool MallocMemoryStats(int* blocks, size_t* total, 107 int histogram[kMallocHistogramSize]); 108 109 // Get a human readable description of the current state of the malloc 110 // data structures. The state is stored as a null-terminated string 111 // in a prefix of "buffer[0,buffer_length-1]". 112 // REQUIRES: buffer_length > 0. 113 virtual void GetStats(char* buffer, int buffer_length); 114 115 // Outputs to "writer" a sample of live objects and the stack traces 116 // that allocated these objects. The format of the returned output 117 // is equivalent to the output of the heap profiler and can 118 // therefore be passed to "pprof". This function is equivalent to 119 // ReadStackTraces. The main difference is that this function returns 120 // serialized data appropriately formatted for use by the pprof tool. 121 // NOTE: by default, tcmalloc does not do any heap sampling, and this 122 // function will always return an empty sample. To get useful 123 // data from GetHeapSample, you must also set the environment 124 // variable TCMALLOC_SAMPLE_PARAMETER to a value such as 524288. 125 virtual void GetHeapSample(MallocExtensionWriter* writer); 126 127 // Outputs to "writer" the stack traces that caused growth in the 128 // address space size. The format of the returned output is 129 // equivalent to the output of the heap profiler and can therefore 130 // be passed to "pprof". This function is equivalent to 131 // ReadHeapGrowthStackTraces. The main difference is that this function 132 // returns serialized data appropriately formatted for use by the 133 // pprof tool. (This does not depend on, or require, 134 // TCMALLOC_SAMPLE_PARAMETER.) 135 virtual void GetHeapGrowthStacks(MallocExtensionWriter* writer); 136 137 // Invokes func(arg, range) for every controlled memory 138 // range. *range is filled in with information about the range. 139 // 140 // This is a best-effort interface useful only for performance 141 // analysis. The implementation may not call func at all. 142 typedef void (RangeFunction)(void*, const base::MallocRange*); 143 virtual void Ranges(void* arg, RangeFunction func); 144 145 // ------------------------------------------------------------------- 146 // Control operations for getting and setting malloc implementation 147 // specific parameters. Some currently useful properties: 148 // 149 // generic 150 // ------- 151 // "generic.current_allocated_bytes" 152 // Number of bytes currently allocated by application 153 // This property is not writable. 154 // 155 // "generic.heap_size" 156 // Number of bytes in the heap == 157 // current_allocated_bytes + 158 // fragmentation + 159 // freed memory regions 160 // This property is not writable. 161 // 162 // tcmalloc 163 // -------- 164 // "tcmalloc.max_total_thread_cache_bytes" 165 // Upper limit on total number of bytes stored across all 166 // per-thread caches. Default: 16MB. 167 // 168 // "tcmalloc.current_total_thread_cache_bytes" 169 // Number of bytes used across all thread caches. 170 // This property is not writable. 171 // 172 // "tcmalloc.pageheap_free_bytes" 173 // Number of bytes in free, mapped pages in page heap. These 174 // bytes can be used to fulfill allocation requests. They 175 // always count towards virtual memory usage, and unless the 176 // underlying memory is swapped out by the OS, they also count 177 // towards physical memory usage. This property is not writable. 178 // 179 // "tcmalloc.pageheap_unmapped_bytes" 180 // Number of bytes in free, unmapped pages in page heap. 181 // These are bytes that have been released back to the OS, 182 // possibly by one of the MallocExtension "Release" calls. 183 // They can be used to fulfill allocation requests, but 184 // typically incur a page fault. They always count towards 185 // virtual memory usage, and depending on the OS, typically 186 // do not count towards physical memory usage. This property 187 // is not writable. 188 // ------------------------------------------------------------------- 189 190 // Get the named "property"'s value. Returns true if the property 191 // is known. Returns false if the property is not a valid property 192 // name for the current malloc implementation. 193 // REQUIRES: property != NULL; value != NULL 194 virtual bool GetNumericProperty(const char* property, size_t* value); 195 196 // Set the named "property"'s value. Returns true if the property 197 // is known and writable. Returns false if the property is not a 198 // valid property name for the current malloc implementation, or 199 // is not writable. 200 // REQUIRES: property != NULL 201 virtual bool SetNumericProperty(const char* property, size_t value); 202 203 // Mark the current thread as "idle". This routine may optionally 204 // be called by threads as a hint to the malloc implementation that 205 // any thread-specific resources should be released. Note: this may 206 // be an expensive routine, so it should not be called too often. 207 // 208 // Also, if the code that calls this routine will go to sleep for 209 // a while, it should take care to not allocate anything between 210 // the call to this routine and the beginning of the sleep. 211 // 212 // Most malloc implementations ignore this routine. 213 virtual void MarkThreadIdle(); 214 215 // Mark the current thread as "busy". This routine should be 216 // called after MarkThreadIdle() if the thread will now do more 217 // work. If this method is not called, performance may suffer. 218 // 219 // Most malloc implementations ignore this routine. 220 virtual void MarkThreadBusy(); 221 222 // Gets the system allocator used by the malloc extension instance. Returns 223 // NULL for malloc implementations that do not support pluggable system 224 // allocators. 225 virtual SysAllocator* GetSystemAllocator(); 226 227 // Sets the system allocator to the specified. 228 // 229 // Users could register their own system allocators for malloc implementation 230 // that supports pluggable system allocators, such as TCMalloc, by doing: 231 // alloc = new MyOwnSysAllocator(); 232 // MallocExtension::instance()->SetSystemAllocator(alloc); 233 // It's up to users whether to fall back (recommended) to the default 234 // system allocator (use GetSystemAllocator() above) or not. The caller is 235 // responsible to any necessary locking. 236 // See tcmalloc/system-alloc.h for the interface and 237 // tcmalloc/memfs_malloc.cc for the examples. 238 // 239 // It's a no-op for malloc implementations that do not support pluggable 240 // system allocators. 241 virtual void SetSystemAllocator(SysAllocator *a); 242 243 // Try to release num_bytes of free memory back to the operating 244 // system for reuse. Use this extension with caution -- to get this 245 // memory back may require faulting pages back in by the OS, and 246 // that may be slow. (Currently only implemented in tcmalloc.) 247 virtual void ReleaseToSystem(size_t num_bytes); 248 249 // Same as ReleaseToSystem() but release as much memory as possible. 250 virtual void ReleaseFreeMemory(); 251 252 // Sets the rate at which we release unused memory to the system. 253 // Zero means we never release memory back to the system. Increase 254 // this flag to return memory faster; decrease it to return memory 255 // slower. Reasonable rates are in the range [0,10]. (Currently 256 // only implemented in tcmalloc). 257 virtual void SetMemoryReleaseRate(double rate); 258 259 // Gets the release rate. Returns a value < 0 if unknown. 260 virtual double GetMemoryReleaseRate(); 261 262 // Returns the estimated number of bytes that will be allocated for 263 // a request of "size" bytes. This is an estimate: an allocation of 264 // SIZE bytes may reserve more bytes, but will never reserve less. 265 // (Currently only implemented in tcmalloc, other implementations 266 // always return SIZE.) 267 // This is equivalent to malloc_good_size() in OS X. 268 virtual size_t GetEstimatedAllocatedSize(size_t size); 269 270 // Returns the actual number N of bytes reserved by tcmalloc for the 271 // pointer p. The client is allowed to use the range of bytes 272 // [p, p+N) in any way it wishes (i.e. N is the "usable size" of this 273 // allocation). This number may be equal to or greater than the number 274 // of bytes requested when p was allocated. 275 // p must have been allocated by this malloc implementation, 276 // must not be an interior pointer -- that is, must be exactly 277 // the pointer returned to by malloc() et al., not some offset 278 // from that -- and should not have been freed yet. p may be NULL. 279 // (Currently only implemented in tcmalloc; other implementations 280 // will return 0.) 281 // This is equivalent to malloc_size() in OS X, malloc_usable_size() 282 // in glibc, and _msize() for windows. 283 virtual size_t GetAllocatedSize(const void* p); 284 285 // Returns kOwned if this malloc implementation allocated the memory 286 // pointed to by p, or kNotOwned if some other malloc implementation 287 // allocated it or p is NULL. May also return kUnknownOwnership if 288 // the malloc implementation does not keep track of ownership. 289 // REQUIRES: p must be a value returned from a previous call to 290 // malloc(), calloc(), realloc(), memalign(), posix_memalign(), 291 // valloc(), pvalloc(), new, or new[], and must refer to memory that 292 // is currently allocated (so, for instance, you should not pass in 293 // a pointer after having called free() on it). 294 enum Ownership { 295 // NOTE: Enum values MUST be kept in sync with the version in 296 // malloc_extension_c.h 297 kUnknownOwnership = 0, 298 kOwned, 299 kNotOwned 300 }; 301 virtual Ownership GetOwnership(const void* p); 302 303 // The current malloc implementation. Always non-NULL. 304 static MallocExtension* instance(); 305 306 // Change the malloc implementation. Typically called by the 307 // malloc implementation during initialization. 308 static void Register(MallocExtension* implementation); 309 310 // On the current thread, return the total number of bytes allocated. 311 // This function is added in Chromium for profiling. 312 // Currently only implemented in tcmalloc. Returns 0 if tcmalloc is not used. 313 // Note that malloc_extension can be used without tcmalloc if gperftools' 314 // heap-profiler is enabled without the tcmalloc memory allocator. 315 static unsigned int GetBytesAllocatedOnCurrentThread(); 316 317 // Returns detailed information about malloc's freelists. For each list, 318 // return a FreeListInfo: 319 struct FreeListInfo { 320 size_t min_object_size; 321 size_t max_object_size; 322 size_t total_bytes_free; 323 const char* type; 324 }; 325 // Each item in the vector refers to a different freelist. The lists 326 // are identified by the range of allocations that objects in the 327 // list can satisfy ([min_object_size, max_object_size]) and the 328 // type of freelist (see below). The current size of the list is 329 // returned in total_bytes_free (which count against a processes 330 // resident and virtual size). 331 // 332 // Currently supported types are: 333 // 334 // "tcmalloc.page{_unmapped}" - tcmalloc's page heap. An entry for each size 335 // class in the page heap is returned. Bytes in "page_unmapped" 336 // are no longer backed by physical memory and do not count against 337 // the resident size of a process. 338 // 339 // "tcmalloc.large{_unmapped}" - tcmalloc's list of objects larger 340 // than the largest page heap size class. Only one "large" 341 // entry is returned. There is no upper-bound on the size 342 // of objects in the large free list; this call returns 343 // kint64max for max_object_size. Bytes in 344 // "large_unmapped" are no longer backed by physical memory 345 // and do not count against the resident size of a process. 346 // 347 // "tcmalloc.central" - tcmalloc's central free-list. One entry per 348 // size-class is returned. Never unmapped. 349 // 350 // "debug.free_queue" - free objects queued by the debug allocator 351 // and not returned to tcmalloc. 352 // 353 // "tcmalloc.thread" - tcmalloc's per-thread caches. Never unmapped. 354 virtual void GetFreeListSizes(std::vector<FreeListInfo>* v); 355 356 // Get a list of stack traces of sampled allocation points. Returns 357 // a pointer to a "new[]-ed" result array, and stores the sample 358 // period in "sample_period". 359 // 360 // The state is stored as a sequence of adjacent entries 361 // in the returned array. Each entry has the following form: 362 // uintptr_t count; // Number of objects with following trace 363 // uintptr_t size; // Total size of objects with following trace 364 // uintptr_t depth; // Number of PC values in stack trace 365 // void* stack[depth]; // PC values that form the stack trace 366 // 367 // The list of entries is terminated by a "count" of 0. 368 // 369 // It is the responsibility of the caller to "delete[]" the returned array. 370 // 371 // May return NULL to indicate no results. 372 // 373 // This is an internal extension. Callers should use the more 374 // convenient "GetHeapSample(string*)" method defined above. 375 virtual void** ReadStackTraces(int* sample_period); 376 377 // Like ReadStackTraces(), but returns stack traces that caused growth 378 // in the address space size. 379 virtual void** ReadHeapGrowthStackTraces(); 380 }; 381 382 namespace base { 383 384 // Information passed per range. More fields may be added later. 385 struct MallocRange { 386 enum Type { 387 INUSE, // Application is using this range 388 FREE, // Range is currently free 389 UNMAPPED, // Backing physical memory has been returned to the OS 390 UNKNOWN, 391 // More enum values may be added in the future 392 }; 393 394 uintptr_t address; // Address of range 395 size_t length; // Byte length of range 396 Type type; // Type of this range 397 double fraction; // Fraction of range that is being used (0 if !INUSE) 398 399 // Perhaps add the following: 400 // - stack trace if this range was sampled 401 // - heap growth stack trace if applicable to this range 402 // - age when allocated (for inuse) or freed (if not in use) 403 }; 404 405 } // namespace base 406 407 #endif // BASE_MALLOC_EXTENSION_H_ 408