sampling_heap_profiler.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_SAMPLING_HEAP_PROFILER_SAMPLING_HEAP_PROFILER_H_
  5. #define BASE_SAMPLING_HEAP_PROFILER_SAMPLING_HEAP_PROFILER_H_
  6. #include <atomic>
  7. #include <unordered_map>
  8. #include <unordered_set>
  9. #include <vector>
  10. #include "base/base_export.h"
  11. #include "base/macros.h"
  12. #include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
  13. #include "base/synchronization/lock.h"
  14. #include "base/thread_annotations.h"
  15. #include "base/threading/thread_id_name_manager.h"
  16. namespace base {
  17. template <typename T>
  18. class NoDestructor;
  19. // The class implements sampling profiling of native memory heap.
  20. // It uses PoissonAllocationSampler to aggregate the heap allocations and
  21. // record samples.
  22. // The recorded samples can then be retrieved using GetSamples method.
  23. class BASE_EXPORT SamplingHeapProfiler
  24. : private PoissonAllocationSampler::SamplesObserver,
  25. public base::ThreadIdNameManager::Observer {
  26. public:
  27. class BASE_EXPORT Sample {
  28. public:
  29. Sample(const Sample&);
  30. ~Sample();
  31. // Allocation size.
  32. size_t size;
  33. // Total size attributed to the sample.
  34. size_t total;
  35. // Type of the allocator.
  36. PoissonAllocationSampler::AllocatorType allocator;
  37. // Context as provided by the allocation hook.
  38. const char* context = nullptr;
  39. // Name of the thread that made the sampled allocation.
  40. const char* thread_name = nullptr;
  41. // Call stack of PC addresses responsible for the allocation.
  42. // If AllocationContextTracker::capture_mode() is in PSEUDO or MIXED modes
  43. // the frame pointers may point to the name strings instead of PCs. In this
  44. // cases all the strings pointers are also reported with |GetStrings| method
  45. // of the |SamplingHeapProfiler|. This way they can be distinguished from
  46. // the PC pointers.
  47. std::vector<void*> stack;
  48. private:
  49. friend class SamplingHeapProfiler;
  50. Sample(size_t size, size_t total, uint32_t ordinal);
  51. uint32_t ordinal;
  52. };
  53. // Starts collecting allocation samples. Returns the current profile_id.
  54. // This value can then be passed to |GetSamples| to retrieve only samples
  55. // recorded since the corresponding |Start| invocation.
  56. uint32_t Start();
  57. // Stops recording allocation samples.
  58. void Stop();
  59. // Sets sampling interval in bytes.
  60. void SetSamplingInterval(size_t sampling_interval);
  61. // Enables recording thread name that made the sampled allocation.
  62. void SetRecordThreadNames(bool value);
  63. // Returns the current thread name.
  64. static const char* CachedThreadName();
  65. // Returns current samples recorded for the profile session.
  66. // If |profile_id| is set to the value returned by the |Start| method,
  67. // it returns only the samples recorded after the corresponding |Start|
  68. // invocation. To retrieve all the collected samples |profile_id| must be
  69. // set to 0.
  70. std::vector<Sample> GetSamples(uint32_t profile_id);
  71. // List of strings used in the profile call stacks.
  72. std::vector<const char*> GetStrings();
  73. // Captures up to |max_entries| stack frames using the buffer pointed by
  74. // |frames|. Puts the number of captured frames into the |count| output
  75. // parameters. Returns the pointer to the topmost frame.
  76. static void** CaptureStackTrace(void** frames,
  77. size_t max_entries,
  78. size_t* count);
  79. static void Init();
  80. static SamplingHeapProfiler* Get();
  81. // ThreadIdNameManager::Observer implementation:
  82. void OnThreadNameChanged(const char* name) override;
  83. private:
  84. SamplingHeapProfiler();
  85. ~SamplingHeapProfiler() override;
  86. // PoissonAllocationSampler::SamplesObserver
  87. void SampleAdded(void* address,
  88. size_t size,
  89. size_t total,
  90. PoissonAllocationSampler::AllocatorType type,
  91. const char* context) override;
  92. void SampleRemoved(void* address) override;
  93. void CaptureMixedStack(const char* context, Sample* sample);
  94. void CaptureNativeStack(const char* context, Sample* sample);
  95. const char* RecordString(const char* string) EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  96. // Mutex to access |samples_| and |strings_|.
  97. Lock mutex_;
  98. // Samples of the currently live allocations.
  99. std::unordered_map<void*, Sample> samples_ GUARDED_BY(mutex_);
  100. // When CaptureMode::PSEUDO_STACK or CaptureMode::MIXED_STACK is enabled
  101. // the call stack contents of samples may contain strings besides
  102. // PC addresses.
  103. // In this case each string pointer is also added to the |strings_| set.
  104. // The set does only contain pointers to static strings that are never
  105. // deleted.
  106. std::unordered_set<const char*> strings_ GUARDED_BY(mutex_);
  107. // Mutex to make |running_sessions_| and Add/Remove samples observer access
  108. // atomic.
  109. Lock start_stop_mutex_;
  110. // Number of the running sessions.
  111. int running_sessions_ = 0;
  112. // Last sample ordinal used to mark samples recorded during single session.
  113. std::atomic<uint32_t> last_sample_ordinal_{1};
  114. // Whether it should record thread names.
  115. std::atomic<bool> record_thread_names_{false};
  116. friend class NoDestructor<SamplingHeapProfiler>;
  117. friend class SamplingHeapProfilerTest;
  118. DISALLOW_COPY_AND_ASSIGN(SamplingHeapProfiler);
  119. };
  120. } // namespace base
  121. #endif // BASE_SAMPLING_HEAP_PROFILER_SAMPLING_HEAP_PROFILER_H_