[go: nahoru, domu]

blob: ce5d8c006c45a4012b46bfa46d0bcd776be208fa [file] [log] [blame]
Ryan Powell30287d42019-08-15 15:48:321// Copyright 2019 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
5#include "base/util/memory_pressure/multi_source_memory_pressure_monitor.h"
6
7#include "base/bind.h"
Hans Wennborgc3cffa62020-04-27 10:09:128#include "base/check_op.h"
Sebastien Marchand6c5354e2020-02-07 19:38:259#include "base/metrics/histogram_functions.h"
Ryan Powell30287d42019-08-15 15:48:3210#include "base/metrics/histogram_macros.h"
Sebastien Marchand6c5354e2020-02-07 19:38:2511#include "base/time/time.h"
Eric Secklerf6c544f2020-06-02 10:49:2112#include "base/trace_event/base_tracing.h"
Ryan Powella68d66fc2019-08-19 21:32:3913#include "base/util/memory_pressure/system_memory_pressure_evaluator.h"
Ryan Powell30287d42019-08-15 15:48:3214
15namespace util {
16
17MultiSourceMemoryPressureMonitor::MultiSourceMemoryPressureMonitor()
18 : current_pressure_level_(
19 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
20 dispatch_callback_(base::BindRepeating(
21 &base::MemoryPressureListener::NotifyMemoryPressure)),
22 aggregator_(this) {
Ryan Powell30287d42019-08-15 15:48:3223}
24
Jenny Wong6592dd42019-09-26 17:25:0725MultiSourceMemoryPressureMonitor::~MultiSourceMemoryPressureMonitor() {
26 // Destroy system evaluator early while the remaining members of this class
27 // still exist. MultiSourceMemoryPressureMonitor implements
28 // MemoryPressureVoteAggregator::Delegate, and
29 // delegate_->OnMemoryPressureLevelChanged() gets indirectly called during
30 // ~SystemMemoryPressureEvaluator().
31 system_evaluator_.reset();
32}
Ryan Powell30287d42019-08-15 15:48:3233
Sebastien Marchandc9d4cd12019-10-03 22:48:0134void MultiSourceMemoryPressureMonitor::Start() {
35 system_evaluator_ =
36 SystemMemoryPressureEvaluator::CreateDefaultSystemEvaluator(this);
37 StartMetricsTimer();
38}
39
Ryan Powell30287d42019-08-15 15:48:3240void MultiSourceMemoryPressureMonitor::StartMetricsTimer() {
41 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Ryan Powellbdc27592019-09-04 22:59:3942 // Unretained is safe here since this task is running on a timer owned by this
43 // object.
Ryan Powell30287d42019-08-15 15:48:3244 metric_timer_.Start(
45 FROM_HERE, MemoryPressureMonitor::kUMAMemoryPressureLevelPeriod,
Ryan Powellbdc27592019-09-04 22:59:3946 BindRepeating(
47 &MultiSourceMemoryPressureMonitor::RecordCurrentPressureLevel,
48 base::Unretained(this)));
Ryan Powell30287d42019-08-15 15:48:3249}
50
51void MultiSourceMemoryPressureMonitor::StopMetricsTimer() {
52 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
53 metric_timer_.Stop();
54}
55
Ryan Powellbdc27592019-09-04 22:59:3956void MultiSourceMemoryPressureMonitor::RecordCurrentPressureLevel() {
57 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
58 RecordMemoryPressure(GetCurrentPressureLevel(), /* ticks = */ 1);
59}
60
Ryan Powell30287d42019-08-15 15:48:3261base::MemoryPressureListener::MemoryPressureLevel
62MultiSourceMemoryPressureMonitor::GetCurrentPressureLevel() const {
63 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
64 return current_pressure_level_;
65}
66
67std::unique_ptr<MemoryPressureVoter>
68MultiSourceMemoryPressureMonitor::CreateVoter() {
69 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Wez861e2922020-03-01 21:14:0070 return aggregator_.CreateVoter();
Ryan Powell30287d42019-08-15 15:48:3271}
72
73void MultiSourceMemoryPressureMonitor::SetDispatchCallback(
74 const DispatchCallback& callback) {
75 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
76 dispatch_callback_ = callback;
77}
78
79void MultiSourceMemoryPressureMonitor::OnMemoryPressureLevelChanged(
80 base::MemoryPressureListener::MemoryPressureLevel level) {
81 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Sebastien Marchand6c5354e2020-02-07 19:38:2582 DCHECK_NE(current_pressure_level_, level);
83
ssidfff7ab42021-03-04 20:03:1184 TRACE_EVENT_INSTANT(
Sebastien Marchand9df1f3d2020-03-23 18:54:3185 "base", "MultiSourceMemoryPressureMonitor::OnMemoryPressureLevelChanged",
ssidfff7ab42021-03-04 20:03:1186 [&](perfetto::EventContext ctx) {
87 auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
88 auto* data = event->set_chrome_memory_pressure_notification();
89 data->set_level(base::MemoryPressureListener::LevelAsTraceEnum(level));
90 });
Sebastien Marchand9df1f3d2020-03-23 18:54:3191
Sebastien Marchand6c5354e2020-02-07 19:38:2592 // Records the duration of the latest pressure session, there are 4
93 // transitions of interest:
94 // - Moderate -> None
95 // - Moderate -> Critical
96 // - Critical -> Moderate
97 // - Critical -> None
98
99 base::TimeTicks now = base::TimeTicks::Now();
100
101 if (current_pressure_level_ !=
102 MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_NONE) {
103 DCHECK(!last_pressure_change_timestamp_.is_null());
104 std::string histogram_name = "Memory.PressureWindowDuration.";
105 switch (current_pressure_level_) {
106 // From:
107 case MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_MODERATE: {
108 // To:
109 if (level == MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_NONE) {
110 histogram_name += "ModerateToNone";
111 } else { // MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL
112 histogram_name += "ModerateToCritical";
113 }
114 break;
115 }
116 // From:
117 case MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL: {
118 // To:
119 if (level == MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_NONE) {
120 histogram_name += "CriticalToNone";
121 } else { // MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_MODERATE
122 histogram_name += "CriticalToModerate";
123 }
124 break;
125 }
126 case MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_NONE:
127 default:
128 break;
129 }
130
131 base::UmaHistogramCustomTimes(
132 histogram_name, now - last_pressure_change_timestamp_,
133 base::TimeDelta::FromSeconds(1), base::TimeDelta::FromMinutes(10), 50);
134 }
135
136 last_pressure_change_timestamp_ = now;
137
Ryan Powell30287d42019-08-15 15:48:32138 current_pressure_level_ = level;
139}
140
141void MultiSourceMemoryPressureMonitor::OnNotifyListenersRequested() {
142 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
143 dispatch_callback_.Run(current_pressure_level_);
144}
145
Ryan Powella68d66fc2019-08-19 21:32:39146void MultiSourceMemoryPressureMonitor::ResetSystemEvaluatorForTesting() {
147 system_evaluator_.reset();
148}
149
Ryan Powell00e61aea2019-09-04 18:33:44150void MultiSourceMemoryPressureMonitor::SetSystemEvaluator(
151 std::unique_ptr<SystemMemoryPressureEvaluator> evaluator) {
152 DCHECK(!system_evaluator_);
153 system_evaluator_ = std::move(evaluator);
154}
155
Ryan Powell30287d42019-08-15 15:48:32156} // namespace util