File: heap_profiler_parameters.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (216 lines) | stat: -rw-r--r-- 8,709 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/heap_profiling/in_process/heap_profiler_parameters.h"

#include "base/check_op.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/sampling_profiler/process_type.h"

namespace heap_profiling {

namespace {

// Platform-specific parameter defaults.

#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
// Default on iOS is equal to mean value of process uptime. Android is
// more similar to iOS than to Desktop.
constexpr base::TimeDelta kDefaultCollectionInterval = base::Minutes(30);
#else
// Default on desktop is once per day.
constexpr base::TimeDelta kDefaultCollectionInterval = base::Days(1);
#endif

// Average 10M bytes per sample.
constexpr int kDefaultSamplingRateBytes = 10'000'000;

// The chance that this client will report heap samples through a metrics
// provider if it's on the stable channel.
#if BUILDFLAG(IS_ANDROID)
// With stable-probability 0.01 we get about 4x as many records as before
// https://crrev.com/c/3309878 landed in 98.0.4742.0, even with ARM64
// disabled. This is too high a volume to process.
constexpr double kDefaultStableProbability = 0.0025;
#else
constexpr double kDefaultStableProbability = 0.01;
#endif

// The chance that this client will report heap samples through a metrics
// provider if it's on a non-stable channel.
constexpr double kDefaultNonStableProbability = 0.5;

// The probability of including a child process in each snapshot that's taken,
// as a percentage from 0 to 100. Defaults to 100, but can be set lower to
// sub-sample process types that are very common (mainly renderers) to keep data
// volume low. Samples from child processes are weighted in inverse proportion
// to the snapshot probability to normalize the aggregated results. Set to 0 to
// disable sampling a process completely.

constexpr base::FeatureParam<int> kGpuSnapshotProbability{
    &kHeapProfilerReporting, "gpu-prob-pct", 100};

constexpr base::FeatureParam<int> kNetworkSnapshotProbability{
    &kHeapProfilerReporting, "network-prob-pct", 100};

// Sample 10% of renderer processes by default, because last time this was
// evaluated (2024-08) the 50th %ile of renderer process count
// (Memory.RenderProcessHost.Count2.All) ranged from 8 on Windows to 18 on Mac.
// 10% is an easy default between 1/18 and 1/8.
constexpr base::FeatureParam<int> kRendererSnapshotProbability{
    &kHeapProfilerReporting, "renderer-prob-pct",
#if BUILDFLAG(IS_CHROMEOS)
    // base::debug::TraceStackFramePointers is crashing in ChromeOS rendererer
    // processes. Disable heap profiling there for now.
    // TODO(crbug.com/402542102): Find the root cause and re-enable.
    0
#else
    10
#endif
};

// Sample 50% of utility processes by default, because last time this was
// evaluated (2024-08) the profiler collected 1.8x as many snapshots on Mac and
// 2.4x as many snapshots on Windows for each browser process snapshot.
constexpr base::FeatureParam<int> kUtilitySnapshotProbability{
    &kHeapProfilerReporting, "utility-prob-pct", 50};

// The sampling rates of each process type, in bytes.

constexpr base::FeatureParam<int> kBrowserSamplingRateBytes{
    &kHeapProfilerReporting, "browser-sampling-rate-bytes",
    kDefaultSamplingRateBytes};

// Use half the threshold used in the browser process, because last time it was
// validated the GPU process allocated a bit over half as much memory at the
// median.
constexpr base::FeatureParam<int> kGpuSamplingRateBytes{
    &kHeapProfilerReporting, "gpu-sampling-rate-bytes",
    kDefaultSamplingRateBytes / 2};

constexpr base::FeatureParam<int> kNetworkSamplingRateBytes{
    &kHeapProfilerReporting, "network-sampling-rate-bytes",
    kDefaultSamplingRateBytes};

constexpr base::FeatureParam<int> kRendererSamplingRateBytes{
    &kHeapProfilerReporting, "renderer-sampling-rate-bytes",
    kDefaultSamplingRateBytes};

// Use 1/10th the threshold used in the browser process, because last time it
// was validated with the default sampling rate (2024-08) the sampler collected
// 6% to 11% as many samples per snapshot in the utility process, depending on
// platform.
constexpr base::FeatureParam<int> kUtilitySamplingRateBytes{
    &kHeapProfilerReporting, "utility-sampling-rate-bytes",
    kDefaultSamplingRateBytes / 10};

// The load factor that should be used by PoissonAllocationSampler's hash set in
// each process type.
constexpr base::FeatureParam<double> kBrowserHashSetLoadFactor{
    &kHeapProfilerReporting, "browser-hash-set-load-factor", 1.0};
constexpr base::FeatureParam<double> kGpuHashSetLoadFactor{
    &kHeapProfilerReporting, "gpu-hash-set-load-factor", 1.0};
constexpr base::FeatureParam<double> kNetworkHashSetLoadFactor{
    &kHeapProfilerReporting, "network-hash-set-load-factor", 1.0};
constexpr base::FeatureParam<double> kRendererHashSetLoadFactor{
    &kHeapProfilerReporting, "renderer-hash-set-load-factor", 1.0};
constexpr base::FeatureParam<double> kUtilityHashSetLoadFactor{
    &kHeapProfilerReporting, "utility-hash-set-load-factor", 1.0};

}  // namespace

BASE_FEATURE(kHeapProfilerReporting,
             "HeapProfilerReporting",
             base::FEATURE_ENABLED_BY_DEFAULT);

const base::FeatureParam<double> kStableProbability{
    &kHeapProfilerReporting, "stable-probability", kDefaultStableProbability};

const base::FeatureParam<double> kNonStableProbability{
    &kHeapProfilerReporting, "nonstable-probability",
    kDefaultNonStableProbability};

const base::FeatureParam<base::TimeDelta> kCollectionInterval{
    &kHeapProfilerReporting, "collection-interval", kDefaultCollectionInterval};

size_t GetSamplingRateForProcess(
    sampling_profiler::ProfilerProcessType process_type) {
  int sampling_rate_bytes;
  switch (process_type) {
    case sampling_profiler::ProfilerProcessType::kBrowser:
      sampling_rate_bytes = kBrowserSamplingRateBytes.Get();
      break;
    case sampling_profiler::ProfilerProcessType::kRenderer:
      sampling_rate_bytes = kRendererSamplingRateBytes.Get();
      break;
    case sampling_profiler::ProfilerProcessType::kGpu:
      sampling_rate_bytes = kGpuSamplingRateBytes.Get();
      break;
    case sampling_profiler::ProfilerProcessType::kUtility:
      sampling_rate_bytes = kUtilitySamplingRateBytes.Get();
      break;
    case sampling_profiler::ProfilerProcessType::kNetworkService:
      sampling_rate_bytes = kNetworkSamplingRateBytes.Get();
      break;
    case sampling_profiler::ProfilerProcessType::kUnknown:
    default:
      // Profiler should not be enabled for these process types.
      NOTREACHED();
  }
  return base::saturated_cast<size_t>(sampling_rate_bytes);
}

int GetSnapshotProbabilityForProcess(
    sampling_profiler::ProfilerProcessType process_type) {
  int snapshot_probability_pct;
  switch (process_type) {
    case sampling_profiler::ProfilerProcessType::kBrowser:
      // Should only be called for child processes.
      NOTREACHED();
    case sampling_profiler::ProfilerProcessType::kGpu:
      snapshot_probability_pct = kGpuSnapshotProbability.Get();
      break;
    case sampling_profiler::ProfilerProcessType::kNetworkService:
      snapshot_probability_pct = kNetworkSnapshotProbability.Get();
      break;
    case sampling_profiler::ProfilerProcessType::kRenderer:
      snapshot_probability_pct = kRendererSnapshotProbability.Get();
      break;
    case sampling_profiler::ProfilerProcessType::kUtility:
      snapshot_probability_pct = kUtilitySnapshotProbability.Get();
      break;
    default:
      // Unsupported process type.
      snapshot_probability_pct = 0;
      break;
  }
  CHECK_GE(snapshot_probability_pct, 0);
  CHECK_LE(snapshot_probability_pct, 100);
  return snapshot_probability_pct;
}

float GetHashSetLoadFactorForProcess(
    sampling_profiler::ProfilerProcessType process_type) {
  switch (process_type) {
    case sampling_profiler::ProfilerProcessType::kBrowser:
      return kBrowserHashSetLoadFactor.Get();
    case sampling_profiler::ProfilerProcessType::kGpu:
      return kGpuHashSetLoadFactor.Get();
    case sampling_profiler::ProfilerProcessType::kNetworkService:
      return kNetworkHashSetLoadFactor.Get();
    case sampling_profiler::ProfilerProcessType::kRenderer:
      return kRendererHashSetLoadFactor.Get();
    case sampling_profiler::ProfilerProcessType::kUtility:
      return kUtilityHashSetLoadFactor.Get();
    default:
      NOTREACHED();
  }
}

}  // namespace heap_profiling