OLD | NEW |
---|---|
1 // Copyright (c) 2005, Google Inc. | 1 // Copyright (c) 2005, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 "If non-zero, dump heap profiling information once every " | 100 "If non-zero, dump heap profiling information once every " |
101 "specified number of bytes deallocated by the program " | 101 "specified number of bytes deallocated by the program " |
102 "since the last dump."); | 102 "since the last dump."); |
103 // We could also add flags that report whenever inuse_bytes changes by | 103 // We could also add flags that report whenever inuse_bytes changes by |
104 // X or -X, but there hasn't been a need for that yet, so we haven't. | 104 // X or -X, but there hasn't been a need for that yet, so we haven't. |
105 DEFINE_int64(heap_profile_inuse_interval, | 105 DEFINE_int64(heap_profile_inuse_interval, |
106 EnvToInt64("HEAP_PROFILE_INUSE_INTERVAL", 100 << 20 /*100MB*/), | 106 EnvToInt64("HEAP_PROFILE_INUSE_INTERVAL", 100 << 20 /*100MB*/), |
107 "If non-zero, dump heap profiling information whenever " | 107 "If non-zero, dump heap profiling information whenever " |
108 "the high-water memory usage mark increases by the specified " | 108 "the high-water memory usage mark increases by the specified " |
109 "number of bytes."); | 109 "number of bytes."); |
110 DEFINE_int64(heap_profile_sec_interval, | |
111 EnvToInt64("HEAP_PROFILE_TIME_INTERVAL", 0), | |
Alexander Potapenko
2011/12/20 13:26:04
Please name the variable accordingly, i.e. heap_pr
Dai Mikurube (NOT FULLTIME)
2011/12/21 05:40:56
Done.
| |
112 "If non-zero, dump heap profiling information once every " | |
113 "specified number of seconds since the last dump."); | |
110 DEFINE_bool(mmap_log, | 114 DEFINE_bool(mmap_log, |
111 EnvToBool("HEAP_PROFILE_MMAP_LOG", false), | 115 EnvToBool("HEAP_PROFILE_MMAP_LOG", false), |
112 "Should mmap/munmap calls be logged?"); | 116 "Should mmap/munmap calls be logged?"); |
113 DEFINE_bool(mmap_profile, | 117 DEFINE_bool(mmap_profile, |
114 EnvToBool("HEAP_PROFILE_MMAP", false), | 118 EnvToBool("HEAP_PROFILE_MMAP", false), |
115 "If heap-profiling is on, also profile mmap, mremap, and sbrk)"); | 119 "If heap-profiling is on, also profile mmap, mremap, and sbrk)"); |
116 DEFINE_bool(only_mmap_profile, | 120 DEFINE_bool(only_mmap_profile, |
117 EnvToBool("HEAP_PROFILE_ONLY_MMAP", false), | 121 EnvToBool("HEAP_PROFILE_ONLY_MMAP", false), |
118 "If heap-profiling is on, only profile mmap, mremap, and sbrk; " | 122 "If heap-profiling is on, only profile mmap, mremap, and sbrk; " |
119 "do not profile malloc/new/etc"); | 123 "do not profile malloc/new/etc"); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 | 165 |
162 // Access to all of these is protected by heap_lock. | 166 // Access to all of these is protected by heap_lock. |
163 static bool is_on = false; // If are on as a subsytem. | 167 static bool is_on = false; // If are on as a subsytem. |
164 static bool dumping = false; // Dumping status to prevent recursion | 168 static bool dumping = false; // Dumping status to prevent recursion |
165 static char* filename_prefix = NULL; // Prefix used for profile file names | 169 static char* filename_prefix = NULL; // Prefix used for profile file names |
166 // (NULL if no need for dumping yet) | 170 // (NULL if no need for dumping yet) |
167 static int dump_count = 0; // How many dumps so far | 171 static int dump_count = 0; // How many dumps so far |
168 static int64 last_dump_alloc = 0; // alloc_size when did we last dump | 172 static int64 last_dump_alloc = 0; // alloc_size when did we last dump |
169 static int64 last_dump_free = 0; // free_size when did we last dump | 173 static int64 last_dump_free = 0; // free_size when did we last dump |
170 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump | 174 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump |
175 static int64 last_dump_time = 0; // The time of the last dump | |
171 | 176 |
172 static HeapProfileTable* heap_profile = NULL; // the heap profile table | 177 static HeapProfileTable* heap_profile = NULL; // the heap profile table |
173 | 178 |
174 //---------------------------------------------------------------------- | 179 //---------------------------------------------------------------------- |
175 // Profile generation | 180 // Profile generation |
176 //---------------------------------------------------------------------- | 181 //---------------------------------------------------------------------- |
177 | 182 |
178 // Input must be a buffer of size at least 1MB. | 183 // Input must be a buffer of size at least 1MB. |
179 static char* DoGetHeapProfileLocked(char* buf, int buflen) { | 184 static char* DoGetHeapProfileLocked(char* buf, int buflen) { |
180 // We used to be smarter about estimating the required memory and | 185 // We used to be smarter about estimating the required memory and |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 snprintf(buf, sizeof(buf), ("%"PRId64" MB freed cumulatively, " | 282 snprintf(buf, sizeof(buf), ("%"PRId64" MB freed cumulatively, " |
278 "%"PRId64" MB currently in use"), | 283 "%"PRId64" MB currently in use"), |
279 total.free_size >> 20, inuse_bytes >> 20); | 284 total.free_size >> 20, inuse_bytes >> 20); |
280 need_to_dump = true; | 285 need_to_dump = true; |
281 } else if (FLAGS_heap_profile_inuse_interval > 0 && | 286 } else if (FLAGS_heap_profile_inuse_interval > 0 && |
282 inuse_bytes > | 287 inuse_bytes > |
283 high_water_mark + FLAGS_heap_profile_inuse_interval) { | 288 high_water_mark + FLAGS_heap_profile_inuse_interval) { |
284 snprintf(buf, sizeof(buf), "%"PRId64" MB currently in use", | 289 snprintf(buf, sizeof(buf), "%"PRId64" MB currently in use", |
285 inuse_bytes >> 20); | 290 inuse_bytes >> 20); |
286 need_to_dump = true; | 291 need_to_dump = true; |
292 } else if (FLAGS_heap_profile_sec_interval > 0 && | |
293 time(NULL) - last_dump_time >= FLAGS_heap_profile_sec_interval) { | |
Alexander Potapenko
2011/12/20 13:26:04
I think you'd better call time(NULL) only once.
Dai Mikurube (NOT FULLTIME)
2011/12/21 05:40:56
Done.
| |
294 snprintf(buf, sizeof(buf), "%d sec since the last dump", | |
295 time(NULL) - last_dump_time); | |
296 need_to_dump = true; | |
297 last_dump_time = time(NULL); | |
287 } | 298 } |
288 if (need_to_dump) { | 299 if (need_to_dump) { |
289 DumpProfileLocked(buf); | 300 DumpProfileLocked(buf); |
290 | 301 |
291 last_dump_alloc = total.alloc_size; | 302 last_dump_alloc = total.alloc_size; |
292 last_dump_free = total.free_size; | 303 last_dump_free = total.free_size; |
293 if (inuse_bytes > high_water_mark) | 304 if (inuse_bytes > high_water_mark) |
294 high_water_mark = inuse_bytes; | 305 high_water_mark = inuse_bytes; |
295 } | 306 } |
296 } | 307 } |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
437 // heap profile even if the application runs out of memory. | 448 // heap profile even if the application runs out of memory. |
438 global_profiler_buffer = | 449 global_profiler_buffer = |
439 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize)); | 450 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize)); |
440 | 451 |
441 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable))) | 452 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable))) |
442 HeapProfileTable(ProfilerMalloc, ProfilerFree); | 453 HeapProfileTable(ProfilerMalloc, ProfilerFree); |
443 | 454 |
444 last_dump_alloc = 0; | 455 last_dump_alloc = 0; |
445 last_dump_free = 0; | 456 last_dump_free = 0; |
446 high_water_mark = 0; | 457 high_water_mark = 0; |
458 last_dump_time = 0; | |
447 | 459 |
448 // We do not reset dump_count so if the user does a sequence of | 460 // We do not reset dump_count so if the user does a sequence of |
449 // HeapProfilerStart/HeapProfileStop, we will get a continuous | 461 // HeapProfilerStart/HeapProfileStop, we will get a continuous |
450 // sequence of profiles. | 462 // sequence of profiles. |
451 | 463 |
452 if (FLAGS_only_mmap_profile == false) { | 464 if (FLAGS_only_mmap_profile == false) { |
453 // Now set the hooks that capture new/delete and malloc/free. | 465 // Now set the hooks that capture new/delete and malloc/free. |
454 RAW_CHECK(MallocHook::AddNewHook(&NewHook), ""); | 466 RAW_CHECK(MallocHook::AddNewHook(&NewHook), ""); |
455 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), ""); | 467 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), ""); |
456 } | 468 } |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
543 | 555 |
544 // class used for finalization -- dumps the heap-profile at program exit | 556 // class used for finalization -- dumps the heap-profile at program exit |
545 struct HeapProfileEndWriter { | 557 struct HeapProfileEndWriter { |
546 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } | 558 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } |
547 }; | 559 }; |
548 | 560 |
549 // We want to make sure tcmalloc is up and running before starting the profiler | 561 // We want to make sure tcmalloc is up and running before starting the profiler |
550 static const TCMallocGuard tcmalloc_initializer; | 562 static const TCMallocGuard tcmalloc_initializer; |
551 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); | 563 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); |
552 static HeapProfileEndWriter heap_profile_end_writer; | 564 static HeapProfileEndWriter heap_profile_end_writer; |
OLD | NEW |