malloc_extension.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2005, 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@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 64static const int kMallocHistogramSize = 64; 65 66// One day, we could support other types of writers (perhaps for C?) 67typedef std::string MallocExtensionWriter; 68 69namespace base { 70struct MallocRange; 71} 72 73// Interface to a pluggable system allocator. 74class 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. 89class 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.central_cache_free_bytes" 173 // Number of free bytes in the central cache that have been 174 // assigned to size classes. They always count towards virtual 175 // memory usage, and unless the underlying memory is swapped out 176 // by the OS, they also count towards physical memory usage. 177 // This property is not writable. 178 // 179 // "tcmalloc.transfer_cache_free_bytes" 180 // Number of free bytes that are waiting to be transfered between 181 // the central cache and a thread cache. They always count 182 // towards virtual memory usage, and unless the underlying memory 183 // is swapped out by the OS, they also count towards physical 184 // memory usage. This property is not writable. 185 // 186 // "tcmalloc.thread_cache_free_bytes" 187 // Number of free bytes in thread caches. They always count 188 // towards virtual memory usage, and unless the underlying memory 189 // is swapped out by the OS, they also count towards physical 190 // memory usage. This property is not writable. 191 // 192 // "tcmalloc.pageheap_free_bytes" 193 // Number of bytes in free, mapped pages in page heap. These 194 // bytes can be used to fulfill allocation requests. They 195 // always count towards virtual memory usage, and unless the 196 // underlying memory is swapped out by the OS, they also count 197 // towards physical memory usage. This property is not writable. 198 // 199 // "tcmalloc.pageheap_unmapped_bytes" 200 // Number of bytes in free, unmapped pages in page heap. 201 // These are bytes that have been released back to the OS, 202 // possibly by one of the MallocExtension "Release" calls. 203 // They can be used to fulfill allocation requests, but 204 // typically incur a page fault. They always count towards 205 // virtual memory usage, and depending on the OS, typically 206 // do not count towards physical memory usage. This property 207 // is not writable. 208 // ------------------------------------------------------------------- 209 210 // Get the named "property"'s value. Returns true if the property 211 // is known. Returns false if the property is not a valid property 212 // name for the current malloc implementation. 213 // REQUIRES: property != NULL; value != NULL 214 virtual bool GetNumericProperty(const char* property, size_t* value); 215 216 // Set the named "property"'s value. Returns true if the property 217 // is known and writable. Returns false if the property is not a 218 // valid property name for the current malloc implementation, or 219 // is not writable. 220 // REQUIRES: property != NULL 221 virtual bool SetNumericProperty(const char* property, size_t value); 222 223 // Mark the current thread as "idle". This routine may optionally 224 // be called by threads as a hint to the malloc implementation that 225 // any thread-specific resources should be released. Note: this may 226 // be an expensive routine, so it should not be called too often. 227 // 228 // Also, if the code that calls this routine will go to sleep for 229 // a while, it should take care to not allocate anything between 230 // the call to this routine and the beginning of the sleep. 231 // 232 // Most malloc implementations ignore this routine. 233 virtual void MarkThreadIdle(); 234 235 // Mark the current thread as "busy". This routine should be 236 // called after MarkThreadIdle() if the thread will now do more 237 // work. If this method is not called, performance may suffer. 238 // 239 // Most malloc implementations ignore this routine. 240 virtual void MarkThreadBusy(); 241 242 // Gets the system allocator used by the malloc extension instance. Returns 243 // NULL for malloc implementations that do not support pluggable system 244 // allocators. 245 virtual SysAllocator* GetSystemAllocator(); 246 247 // Sets the system allocator to the specified. 248 // 249 // Users could register their own system allocators for malloc implementation 250 // that supports pluggable system allocators, such as TCMalloc, by doing: 251 // alloc = new MyOwnSysAllocator(); 252 // MallocExtension::instance()->SetSystemAllocator(alloc); 253 // It's up to users whether to fall back (recommended) to the default 254 // system allocator (use GetSystemAllocator() above) or not. The caller is 255 // responsible to any necessary locking. 256 // See tcmalloc/system-alloc.h for the interface and 257 // tcmalloc/memfs_malloc.cc for the examples. 258 // 259 // It's a no-op for malloc implementations that do not support pluggable 260 // system allocators. 261 virtual void SetSystemAllocator(SysAllocator *a); 262 263 // Try to release num_bytes of free memory back to the operating 264 // system for reuse. Use this extension with caution -- to get this 265 // memory back may require faulting pages back in by the OS, and 266 // that may be slow. (Currently only implemented in tcmalloc.) 267 virtual void ReleaseToSystem(size_t num_bytes); 268 269 // Same as ReleaseToSystem() but release as much memory as possible. 270 virtual void ReleaseFreeMemory(); 271 272 // Sets the rate at which we release unused memory to the system. 273 // Zero means we never release memory back to the system. Increase 274 // this flag to return memory faster; decrease it to return memory 275 // slower. Reasonable rates are in the range [0,10]. (Currently 276 // only implemented in tcmalloc). 277 virtual void SetMemoryReleaseRate(double rate); 278 279 // Gets the release rate. Returns a value < 0 if unknown. 280 virtual double GetMemoryReleaseRate(); 281 282 // Returns the estimated number of bytes that will be allocated for 283 // a request of "size" bytes. This is an estimate: an allocation of 284 // SIZE bytes may reserve more bytes, but will never reserve less. 285 // (Currently only implemented in tcmalloc, other implementations 286 // always return SIZE.) 287 // This is equivalent to malloc_good_size() in OS X. 288 virtual size_t GetEstimatedAllocatedSize(size_t size); 289 290 // Returns the actual number N of bytes reserved by tcmalloc for the 291 // pointer p. The client is allowed to use the range of bytes 292 // [p, p+N) in any way it wishes (i.e. N is the "usable size" of this 293 // allocation). This number may be equal to or greater than the number 294 // of bytes requested when p was allocated. 295 // p must have been allocated by this malloc implementation, 296 // must not be an interior pointer -- that is, must be exactly 297 // the pointer returned to by malloc() et al., not some offset 298 // from that -- and should not have been freed yet. p may be NULL. 299 // (Currently only implemented in tcmalloc; other implementations 300 // will return 0.) 301 // This is equivalent to malloc_size() in OS X, malloc_usable_size() 302 // in glibc, and _msize() for windows. 303 virtual size_t GetAllocatedSize(const void* p); 304 305 // Returns kOwned if this malloc implementation allocated the memory 306 // pointed to by p, or kNotOwned if some other malloc implementation 307 // allocated it or p is NULL. May also return kUnknownOwnership if 308 // the malloc implementation does not keep track of ownership. 309 // REQUIRES: p must be a value returned from a previous call to 310 // malloc(), calloc(), realloc(), memalign(), posix_memalign(), 311 // valloc(), pvalloc(), new, or new[], and must refer to memory that 312 // is currently allocated (so, for instance, you should not pass in 313 // a pointer after having called free() on it). 314 enum Ownership { 315 // NOTE: Enum values MUST be kept in sync with the version in 316 // malloc_extension_c.h 317 kUnknownOwnership = 0, 318 kOwned, 319 kNotOwned 320 }; 321 virtual Ownership GetOwnership(const void* p); 322 323 // The current malloc implementation. Always non-NULL. 324 static MallocExtension* instance(); 325 326 // Change the malloc implementation. Typically called by the 327 // malloc implementation during initialization. 328 static void Register(MallocExtension* implementation); 329 330 // Returns detailed information about malloc's freelists. For each list, 331 // return a FreeListInfo: 332 struct FreeListInfo { 333 size_t min_object_size; 334 size_t max_object_size; 335 size_t total_bytes_free; 336 const char* type; 337 }; 338 // Each item in the vector refers to a different freelist. The lists 339 // are identified by the range of allocations that objects in the 340 // list can satisfy ([min_object_size, max_object_size]) and the 341 // type of freelist (see below). The current size of the list is 342 // returned in total_bytes_free (which count against a processes 343 // resident and virtual size). 344 // 345 // Currently supported types are: 346 // 347 // "tcmalloc.page{_unmapped}" - tcmalloc's page heap. An entry for each size 348 // class in the page heap is returned. Bytes in "page_unmapped" 349 // are no longer backed by physical memory and do not count against 350 // the resident size of a process. 351 // 352 // "tcmalloc.large{_unmapped}" - tcmalloc's list of objects larger 353 // than the largest page heap size class. Only one "large" 354 // entry is returned. There is no upper-bound on the size 355 // of objects in the large free list; this call returns 356 // kint64max for max_object_size. Bytes in 357 // "large_unmapped" are no longer backed by physical memory 358 // and do not count against the resident size of a process. 359 // 360 // "tcmalloc.central" - tcmalloc's central free-list. One entry per 361 // size-class is returned. Never unmapped. 362 // 363 // "debug.free_queue" - free objects queued by the debug allocator 364 // and not returned to tcmalloc. 365 // 366 // "tcmalloc.thread" - tcmalloc's per-thread caches. Never unmapped. 367 virtual void GetFreeListSizes(std::vector<FreeListInfo>* v); 368 369 // Get a list of stack traces of sampled allocation points. Returns 370 // a pointer to a "new[]-ed" result array, and stores the sample 371 // period in "sample_period". 372 // 373 // The state is stored as a sequence of adjacent entries 374 // in the returned array. Each entry has the following form: 375 // uintptr_t count; // Number of objects with following trace 376 // uintptr_t size; // Total size of objects with following trace 377 // uintptr_t depth; // Number of PC values in stack trace 378 // void* stack[depth]; // PC values that form the stack trace 379 // 380 // The list of entries is terminated by a "count" of 0. 381 // 382 // It is the responsibility of the caller to "delete[]" the returned array. 383 // 384 // May return NULL to indicate no results. 385 // 386 // This is an internal extension. Callers should use the more 387 // convenient "GetHeapSample(string*)" method defined above. 388 virtual void** ReadStackTraces(int* sample_period); 389 390 // Like ReadStackTraces(), but returns stack traces that caused growth 391 // in the address space size. 392 virtual void** ReadHeapGrowthStackTraces(); 393}; 394 395namespace base { 396 397// Information passed per range. More fields may be added later. 398struct MallocRange { 399 enum Type { 400 INUSE, // Application is using this range 401 FREE, // Range is currently free 402 UNMAPPED, // Backing physical memory has been returned to the OS 403 UNKNOWN, 404 // More enum values may be added in the future 405 }; 406 407 uintptr_t address; // Address of range 408 size_t length; // Byte length of range 409 Type type; // Type of this range 410 double fraction; // Fraction of range that is being used (0 if !INUSE) 411 412 // Perhaps add the following: 413 // - stack trace if this range was sampled 414 // - heap growth stack trace if applicable to this range 415 // - age when allocated (for inuse) or freed (if not in use) 416}; 417 418} // namespace base 419 420#endif // BASE_MALLOC_EXTENSION_H_ 421