Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1216)

Side by Side Diff: base/trace_event/memory_dump_scheduler.cc

Issue 2736283003: [memory-infra] MemoryDumpScheduler follows config for time between dumps (Closed)
Patch Set: rebase. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/memory_dump_scheduler.h" 5 #include "base/trace_event/memory_dump_scheduler.h"
6 6
7 #include "base/process/process_metrics.h" 7 #include "base/process/process_metrics.h"
8 #include "base/single_thread_task_runner.h" 8 #include "base/single_thread_task_runner.h"
9 #include "base/threading/thread_task_runner_handle.h" 9 #include "base/threading/thread_task_runner_handle.h"
10 #include "base/trace_event/memory_dump_manager.h" 10 #include "base/trace_event/memory_dump_manager.h"
(...skipping 24 matching lines...) Expand all
35 #endif 35 #endif
36 } 36 }
37 37
38 MemoryDumpScheduler::~MemoryDumpScheduler() {} 38 MemoryDumpScheduler::~MemoryDumpScheduler() {}
39 39
40 void MemoryDumpScheduler::AddTrigger(MemoryDumpType trigger_type, 40 void MemoryDumpScheduler::AddTrigger(MemoryDumpType trigger_type,
41 MemoryDumpLevelOfDetail level_of_detail, 41 MemoryDumpLevelOfDetail level_of_detail,
42 uint32_t min_time_between_dumps_ms) { 42 uint32_t min_time_between_dumps_ms) {
43 if (trigger_type == MemoryDumpType::PEAK_MEMORY_USAGE) { 43 if (trigger_type == MemoryDumpType::PEAK_MEMORY_USAGE) {
44 DCHECK(!periodic_state_.is_configured); 44 DCHECK(!periodic_state_.is_configured);
45 DCHECK(!polling_state_.is_configured); 45 DCHECK_EQ(PollingTriggerState::DISABLED, polling_state_.current_state);
46 DCHECK_NE(0u, min_time_between_dumps_ms); 46 DCHECK_NE(0u, min_time_between_dumps_ms);
47 47
48 polling_state_.level_of_detail = level_of_detail; 48 polling_state_.level_of_detail = level_of_detail;
49 polling_state_.min_polls_between_dumps = 49 polling_state_.min_polls_between_dumps =
50 (min_time_between_dumps_ms + polling_state_.polling_interval_ms - 1) / 50 (min_time_between_dumps_ms + polling_state_.polling_interval_ms - 1) /
51 polling_state_.polling_interval_ms; 51 polling_state_.polling_interval_ms;
52 polling_state_.is_configured = true; 52 polling_state_.current_state = PollingTriggerState::CONFIGURED;
53 } else if (trigger_type == MemoryDumpType::PERIODIC_INTERVAL) { 53 } else if (trigger_type == MemoryDumpType::PERIODIC_INTERVAL) {
54 DCHECK(!polling_state_.is_configured); 54 DCHECK_EQ(PollingTriggerState::DISABLED, polling_state_.current_state);
55 periodic_state_.is_configured = true; 55 periodic_state_.is_configured = true;
56 DCHECK_NE(0u, min_time_between_dumps_ms); 56 DCHECK_NE(0u, min_time_between_dumps_ms);
57 switch (level_of_detail) { 57 switch (level_of_detail) {
58 case MemoryDumpLevelOfDetail::BACKGROUND: 58 case MemoryDumpLevelOfDetail::BACKGROUND:
59 break; 59 break;
60 case MemoryDumpLevelOfDetail::LIGHT: 60 case MemoryDumpLevelOfDetail::LIGHT:
61 DCHECK_EQ(0u, periodic_state_.light_dump_period_ms); 61 DCHECK_EQ(0u, periodic_state_.light_dump_period_ms);
62 periodic_state_.light_dump_period_ms = min_time_between_dumps_ms; 62 periodic_state_.light_dump_period_ms = min_time_between_dumps_ms;
63 break; 63 break;
64 case MemoryDumpLevelOfDetail::DETAILED: 64 case MemoryDumpLevelOfDetail::DETAILED:
(...skipping 20 matching lines...) Expand all
85 periodic_state_.min_timer_period_ms; 85 periodic_state_.min_timer_period_ms;
86 86
87 periodic_state_.dump_count = 0; 87 periodic_state_.dump_count = 0;
88 periodic_state_.timer.Start( 88 periodic_state_.timer.Start(
89 FROM_HERE, 89 FROM_HERE,
90 TimeDelta::FromMilliseconds(periodic_state_.min_timer_period_ms), 90 TimeDelta::FromMilliseconds(periodic_state_.min_timer_period_ms),
91 Bind(&MemoryDumpScheduler::RequestPeriodicGlobalDump, Unretained(this))); 91 Bind(&MemoryDumpScheduler::RequestPeriodicGlobalDump, Unretained(this)));
92 } 92 }
93 93
94 void MemoryDumpScheduler::NotifyPollingSupported() { 94 void MemoryDumpScheduler::NotifyPollingSupported() {
95 if (!polling_state_.is_configured || polling_state_.is_polling_enabled) 95 if (polling_state_.current_state != PollingTriggerState::CONFIGURED)
96 return; 96 return;
97 polling_state_.is_polling_enabled = true; 97 polling_state_.current_state = PollingTriggerState::ENABLED;
98 for (uint32_t i = 0; 98
99 i < PollingTriggerState::kNumTotalsTrackedForPeakDetection; ++i) { 99 polling_state_.ResetTotals();
100 polling_state_.last_memory_totals_kb[i] = 0;
101 }
102 polling_state_.last_memory_totals_kb_index = 0;
103 polling_state_.num_polls_from_last_dump = 0;
104 polling_state_.last_dump_memory_total = 0;
105 polling_state_.polling_task_runner->PostTask( 100 polling_state_.polling_task_runner->PostTask(
106 FROM_HERE, 101 FROM_HERE,
107 Bind(&MemoryDumpScheduler::PollMemoryOnPollingThread, Unretained(this))); 102 Bind(&MemoryDumpScheduler::PollMemoryOnPollingThread, Unretained(this)));
108 } 103 }
109 104
105 void MemoryDumpScheduler::NotifyDumpTriggered() {
106 if (polling_state_.polling_task_runner &&
107 ThreadTaskRunnerHandle::Get() != polling_state_.polling_task_runner) {
Primiano Tucci (use gerrit) 2017/03/10 10:35:39 do you really want to compare the TaskRunnerHandle
ssid 2017/03/10 23:51:10 Yes my bad. Fixed it.
108 polling_state_.polling_task_runner->PostTask(
109 FROM_HERE,
110 Bind(&MemoryDumpScheduler::NotifyDumpTriggered, Unretained(this)));
Primiano Tucci (use gerrit) 2017/03/10 10:35:39 Also I just realized that these Unretained aren't
ssid 2017/03/10 14:57:37 The reason why the unretained should be safe here
111 return;
112 }
113 if (polling_state_.current_state != PollingTriggerState::ENABLED)
114 return;
115
116 polling_state_.ResetTotals();
117 }
118
110 void MemoryDumpScheduler::DisableAllTriggers() { 119 void MemoryDumpScheduler::DisableAllTriggers() {
111 if (periodic_state_.timer.IsRunning()) 120 if (periodic_state_.timer.IsRunning())
112 periodic_state_.timer.Stop(); 121 periodic_state_.timer.Stop();
113 DisablePolling(); 122 DisablePolling();
114 } 123 }
115 124
116 void MemoryDumpScheduler::DisablePolling() { 125 void MemoryDumpScheduler::DisablePolling() {
117 if (ThreadTaskRunnerHandle::Get() != polling_state_.polling_task_runner) { 126 if (ThreadTaskRunnerHandle::Get() != polling_state_.polling_task_runner) {
118 if (polling_state_.polling_task_runner->PostTask( 127 if (polling_state_.polling_task_runner->PostTask(
119 FROM_HERE, 128 FROM_HERE,
120 Bind(&MemoryDumpScheduler::DisablePolling, Unretained(this)))) 129 Bind(&MemoryDumpScheduler::DisablePolling, Unretained(this))))
121 return; 130 return;
122 } 131 }
123 polling_state_.is_polling_enabled = false; 132 polling_state_.current_state = PollingTriggerState::DISABLED;
124 polling_state_.is_configured = false;
125 polling_state_.polling_task_runner = nullptr; 133 polling_state_.polling_task_runner = nullptr;
126 } 134 }
127 135
128 // static 136 // static
129 void MemoryDumpScheduler::SetPollingIntervalForTesting(uint32_t interval) { 137 void MemoryDumpScheduler::SetPollingIntervalForTesting(uint32_t interval) {
130 g_polling_interval_ms_for_testing = interval; 138 g_polling_interval_ms_for_testing = interval;
131 } 139 }
132 140
133 bool MemoryDumpScheduler::IsPeriodicTimerRunningForTesting() { 141 bool MemoryDumpScheduler::IsPeriodicTimerRunningForTesting() {
134 return periodic_state_.timer.IsRunning(); 142 return periodic_state_.timer.IsRunning();
135 } 143 }
136 144
137 void MemoryDumpScheduler::RequestPeriodicGlobalDump() { 145 void MemoryDumpScheduler::RequestPeriodicGlobalDump() {
138 MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND; 146 MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND;
139 if (periodic_state_.light_dumps_rate > 0 && 147 if (periodic_state_.light_dumps_rate > 0 &&
140 periodic_state_.dump_count % periodic_state_.light_dumps_rate == 0) 148 periodic_state_.dump_count % periodic_state_.light_dumps_rate == 0)
141 level_of_detail = MemoryDumpLevelOfDetail::LIGHT; 149 level_of_detail = MemoryDumpLevelOfDetail::LIGHT;
142 if (periodic_state_.heavy_dumps_rate > 0 && 150 if (periodic_state_.heavy_dumps_rate > 0 &&
143 periodic_state_.dump_count % periodic_state_.heavy_dumps_rate == 0) 151 periodic_state_.dump_count % periodic_state_.heavy_dumps_rate == 0)
144 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; 152 level_of_detail = MemoryDumpLevelOfDetail::DETAILED;
145 ++periodic_state_.dump_count; 153 ++periodic_state_.dump_count;
146 154
147 mdm_->RequestGlobalDump(MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); 155 mdm_->RequestGlobalDump(MemoryDumpType::PERIODIC_INTERVAL, level_of_detail);
148 } 156 }
149 157
150 void MemoryDumpScheduler::PollMemoryOnPollingThread() { 158 void MemoryDumpScheduler::PollMemoryOnPollingThread() {
151 if (!polling_state_.is_configured) 159 if (polling_state_.current_state != PollingTriggerState::ENABLED)
152 return; 160 return;
153 161
154 uint64_t polled_memory = 0; 162 uint64_t polled_memory = 0;
155 bool res = mdm_->PollFastMemoryTotal(&polled_memory); 163 bool res = mdm_->PollFastMemoryTotal(&polled_memory);
156 DCHECK(res); 164 DCHECK(res);
157 if (polling_state_.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { 165 if (polling_state_.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) {
158 TRACE_COUNTER1(MemoryDumpManager::kTraceCategory, "PolledMemoryMB", 166 TRACE_COUNTER1(MemoryDumpManager::kTraceCategory, "PolledMemoryMB",
159 polled_memory / 1024 / 1024); 167 polled_memory / 1024 / 1024);
160 } 168 }
161 169
(...skipping 29 matching lines...) Expand all
191 } else if (polling_state_.min_polls_between_dumps > 199 } else if (polling_state_.min_polls_between_dumps >
192 polling_state_.num_polls_from_last_dump) { 200 polling_state_.num_polls_from_last_dump) {
193 return false; 201 return false;
194 } 202 }
195 203
196 int64_t increase_from_last_dump = 204 int64_t increase_from_last_dump =
197 current_memory_total - polling_state_.last_dump_memory_total; 205 current_memory_total - polling_state_.last_dump_memory_total;
198 should_dump |= 206 should_dump |=
199 increase_from_last_dump > polling_state_.memory_increase_threshold; 207 increase_from_last_dump > polling_state_.memory_increase_threshold;
200 should_dump |= IsCurrentSamplePeak(current_memory_total); 208 should_dump |= IsCurrentSamplePeak(current_memory_total);
201 if (should_dump) { 209 if (should_dump)
202 polling_state_.last_dump_memory_total = current_memory_total; 210 polling_state_.ResetTotals();
203 polling_state_.num_polls_from_last_dump = 0;
204 for (uint32_t i = 0;
205 i < PollingTriggerState::kNumTotalsTrackedForPeakDetection; ++i) {
206 polling_state_.last_memory_totals_kb[i] = 0;
207 }
208 polling_state_.last_memory_totals_kb_index = 0;
209 }
210 return should_dump; 211 return should_dump;
211 } 212 }
212 213
213 bool MemoryDumpScheduler::IsCurrentSamplePeak( 214 bool MemoryDumpScheduler::IsCurrentSamplePeak(
214 uint64_t current_memory_total_bytes) { 215 uint64_t current_memory_total_bytes) {
215 uint64_t current_memory_total_kb = current_memory_total_bytes / 1024; 216 uint64_t current_memory_total_kb = current_memory_total_bytes / 1024;
216 polling_state_.last_memory_totals_kb_index = 217 polling_state_.last_memory_totals_kb_index =
217 (polling_state_.last_memory_totals_kb_index + 1) % 218 (polling_state_.last_memory_totals_kb_index + 1) %
218 PollingTriggerState::kNumTotalsTrackedForPeakDetection; 219 PollingTriggerState::kNumTotalsTrackedForPeakDetection;
219 uint64_t mean = 0; 220 uint64_t mean = 0;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 heavy_dumps_rate(0), 261 heavy_dumps_rate(0),
261 light_dump_period_ms(0), 262 light_dump_period_ms(0),
262 heavy_dump_period_ms(0) {} 263 heavy_dump_period_ms(0) {}
263 264
264 MemoryDumpScheduler::PeriodicTriggerState::~PeriodicTriggerState() { 265 MemoryDumpScheduler::PeriodicTriggerState::~PeriodicTriggerState() {
265 DCHECK(!timer.IsRunning()); 266 DCHECK(!timer.IsRunning());
266 } 267 }
267 268
268 MemoryDumpScheduler::PollingTriggerState::PollingTriggerState( 269 MemoryDumpScheduler::PollingTriggerState::PollingTriggerState(
269 scoped_refptr<SingleThreadTaskRunner> polling_task_runner) 270 scoped_refptr<SingleThreadTaskRunner> polling_task_runner)
270 : is_configured(false), 271 : current_state(DISABLED),
271 is_polling_enabled(false),
272 level_of_detail(MemoryDumpLevelOfDetail::FIRST), 272 level_of_detail(MemoryDumpLevelOfDetail::FIRST),
273 polling_task_runner(polling_task_runner), 273 polling_task_runner(polling_task_runner),
274 polling_interval_ms(g_polling_interval_ms_for_testing 274 polling_interval_ms(g_polling_interval_ms_for_testing
275 ? g_polling_interval_ms_for_testing 275 ? g_polling_interval_ms_for_testing
276 : kMemoryTotalsPollingInterval), 276 : kMemoryTotalsPollingInterval),
277 min_polls_between_dumps(0), 277 min_polls_between_dumps(0),
278 num_polls_from_last_dump(0), 278 num_polls_from_last_dump(0),
279 last_dump_memory_total(0), 279 last_dump_memory_total(0),
280 memory_increase_threshold(kDefaultMemoryIncreaseThreshold), 280 memory_increase_threshold(kDefaultMemoryIncreaseThreshold),
281 last_memory_totals_kb_index(0) {} 281 last_memory_totals_kb_index(0) {}
282 282
283 MemoryDumpScheduler::PollingTriggerState::~PollingTriggerState() { 283 MemoryDumpScheduler::PollingTriggerState::~PollingTriggerState() {
284 DCHECK(!polling_task_runner); 284 DCHECK(!polling_task_runner);
285 } 285 }
286 286
287 void MemoryDumpScheduler::PollingTriggerState::ResetTotals() {
288 if (last_memory_totals_kb_index) {
289 last_dump_memory_total =
290 last_memory_totals_kb[last_memory_totals_kb_index] * 1024;
291 }
292 num_polls_from_last_dump = 0;
293 for (uint32_t i = 0; i < kNumTotalsTrackedForPeakDetection; ++i)
294 last_memory_totals_kb[i] = 0;
295 last_memory_totals_kb_index = 0;
296 }
297
287 } // namespace trace_event 298 } // namespace trace_event
288 } // namespace base 299 } // namespace base
OLDNEW
« no previous file with comments | « base/trace_event/memory_dump_scheduler.h ('k') | services/resource_coordinator/memory/coordinator/coordinator_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698