Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/trace_event/heap_profiler_heap_dump_writer.h" | 5 #include "base/trace_event/heap_profiler_heap_dump_writer.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <iterator> | 10 #include <iterator> |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 // no bucket is discarded is doing a heap sort, which is O(n log n). | 128 // no bucket is discarded is doing a heap sort, which is O(n log n). |
| 129 std::make_heap(buckets.begin(), buckets.end()); | 129 std::make_heap(buckets.begin(), buckets.end()); |
| 130 | 130 |
| 131 // Keep including buckets until adding one would increase the number of | 131 // Keep including buckets until adding one would increase the number of |
| 132 // bytes accounted for by less than 0.8 percent. This simple heuristic works | 132 // bytes accounted for by less than 0.8 percent. This simple heuristic works |
| 133 // quite well. The large buckets end up in [it, end()), [begin(), it) is the | 133 // quite well. The large buckets end up in [it, end()), [begin(), it) is the |
| 134 // part that contains the max-heap of small buckets. | 134 // part that contains the max-heap of small buckets. |
| 135 size_t accounted_for = 0; | 135 size_t accounted_for = 0; |
| 136 std::vector<Bucket>::iterator it; | 136 std::vector<Bucket>::iterator it; |
| 137 for (it = buckets.end(); it != buckets.begin(); --it) { | 137 for (it = buckets.end(); it != buckets.begin(); --it) { |
| 138 // Compute the contribution to the number of bytes accounted for as a | 138 // Compute the total accounted amount of bytes |
| 139 // fraction of 125 (in increments of 0.8 percent). Anything less than 1/125 | 139 // If next bucket increase this amount by less then 0.8% just skip the tail |
|
Primiano Tucci (use gerrit)
2016/04/06 08:20:44
I'd add a "(1/125)" after 0.8% otherwise It's not
| |
| 140 // is rounded down to 0 due to integer division. Buckets are iterated by | |
| 141 // descending size, so later buckets cannot have a larger contribution than | |
| 142 // this one. | |
| 143 accounted_for += buckets.front().size; | 140 accounted_for += buckets.front().size; |
| 144 size_t contribution = buckets.front().size * 125 / accounted_for; | 141 if (buckets.front().size < (accounted_for / 125)) |
| 145 if (contribution == 0) | |
| 146 break; | 142 break; |
| 147 | 143 |
| 148 // Put the largest bucket in [begin, it) at |it - 1| and max-heapify | 144 // Put the largest bucket in [begin, it) at |it - 1| and max-heapify |
| 149 // [begin, it - 1). This puts the next largest bucket at |buckets.front()|. | 145 // [begin, it - 1). This puts the next largest bucket at |buckets.front()|. |
| 150 std::pop_heap(buckets.begin(), it); | 146 std::pop_heap(buckets.begin(), it); |
| 151 } | 147 } |
| 152 | 148 |
| 153 // At this point, |buckets| looks like this (numbers are bucket sizes): | 149 // At this point, |buckets| looks like this (numbers are bucket sizes): |
| 154 // | 150 // |
| 155 // <-- max-heap of small buckets ---> | 151 // <-- max-heap of small buckets ---> |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 BreakDown(subbucket); | 223 BreakDown(subbucket); |
| 228 } | 224 } |
| 229 | 225 |
| 230 const std::set<Entry>& HeapDumpWriter::Summarize( | 226 const std::set<Entry>& HeapDumpWriter::Summarize( |
| 231 const hash_map<AllocationContext, size_t>& bytes_by_context) { | 227 const hash_map<AllocationContext, size_t>& bytes_by_context) { |
| 232 // Start with one bucket that represents the entire heap. Iterate by | 228 // Start with one bucket that represents the entire heap. Iterate by |
| 233 // reference, because the allocation contexts are going to point to allocation | 229 // reference, because the allocation contexts are going to point to allocation |
| 234 // contexts stored in |bytes_by_context|. | 230 // contexts stored in |bytes_by_context|. |
| 235 Bucket root_bucket; | 231 Bucket root_bucket; |
| 236 for (const auto& context_and_size : bytes_by_context) { | 232 for (const auto& context_and_size : bytes_by_context) { |
| 233 DCHECK_GT(context_and_size.second, 0u); | |
| 237 const AllocationContext* context = &context_and_size.first; | 234 const AllocationContext* context = &context_and_size.first; |
| 238 const size_t size = context_and_size.second; | 235 const size_t size = context_and_size.second; |
| 239 root_bucket.bytes_by_context.push_back(std::make_pair(context, size)); | 236 root_bucket.bytes_by_context.push_back(std::make_pair(context, size)); |
| 240 root_bucket.size += size; | 237 root_bucket.size += size; |
| 241 } | 238 } |
| 242 | 239 |
| 243 AddEntryForBucket(root_bucket); | 240 AddEntryForBucket(root_bucket); |
| 244 | 241 |
| 245 // Recursively break down the heap and fill |entries_| with entries to dump. | 242 // Recursively break down the heap and fill |entries_| with entries to dump. |
| 246 BreakDown(root_bucket); | 243 BreakDown(root_bucket); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 293 const hash_map<AllocationContext, size_t>& bytes_by_size, | 290 const hash_map<AllocationContext, size_t>& bytes_by_size, |
| 294 StackFrameDeduplicator* stack_frame_deduplicator, | 291 StackFrameDeduplicator* stack_frame_deduplicator, |
| 295 TypeNameDeduplicator* type_name_deduplicator) { | 292 TypeNameDeduplicator* type_name_deduplicator) { |
| 296 internal::HeapDumpWriter writer(stack_frame_deduplicator, | 293 internal::HeapDumpWriter writer(stack_frame_deduplicator, |
| 297 type_name_deduplicator); | 294 type_name_deduplicator); |
| 298 return Serialize(writer.Summarize(bytes_by_size)); | 295 return Serialize(writer.Summarize(bytes_by_size)); |
| 299 } | 296 } |
| 300 | 297 |
| 301 } // namespace trace_event | 298 } // namespace trace_event |
| 302 } // namespace base | 299 } // namespace base |
| OLD | NEW |