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 "chrome/browser/chromeos/resource_reporter/resource_reporter.h" | 5 #include "chrome/browser/chromeos/resource_reporter/resource_reporter.h" |
| 6 | 6 |
| 7 #include <cstdint> | 7 #include <cstdint> |
| 8 #include <queue> | 8 #include <queue> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/memory/memory_coordinator_client_registry.h" | |
| 12 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 13 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/sys_info.h" | 16 #include "base/sys_info.h" |
| 16 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 17 #include "chrome/browser/task_manager/task_manager_interface.h" | 18 #include "chrome/browser/task_manager/task_manager_interface.h" |
| 18 #include "components/rappor/rappor_service.h" | 19 #include "components/rappor/rappor_service.h" |
| 19 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 20 | 21 |
| 21 namespace chromeos { | 22 namespace chromeos { |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 } | 241 } |
| 241 | 242 |
| 242 // static | 243 // static |
| 243 const size_t ResourceReporter::kTopConsumersCount = 10U; | 244 const size_t ResourceReporter::kTopConsumersCount = 10U; |
| 244 | 245 |
| 245 ResourceReporter::ResourceReporter() | 246 ResourceReporter::ResourceReporter() |
| 246 : TaskManagerObserver(base::TimeDelta::FromSeconds(kRefreshIntervalSeconds), | 247 : TaskManagerObserver(base::TimeDelta::FromSeconds(kRefreshIntervalSeconds), |
| 247 task_manager::REFRESH_TYPE_CPU | | 248 task_manager::REFRESH_TYPE_CPU | |
| 248 task_manager::REFRESH_TYPE_MEMORY | | 249 task_manager::REFRESH_TYPE_MEMORY | |
| 249 task_manager::REFRESH_TYPE_PRIORITY), | 250 task_manager::REFRESH_TYPE_PRIORITY), |
| 250 system_cpu_cores_range_(GetCurrentSystemCpuCoresRange()) {} | 251 system_cpu_cores_range_(GetCurrentSystemCpuCoresRange()) { |
| 252 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); | |
| 253 } | |
| 251 | 254 |
| 252 // static | 255 // static |
| 253 std::unique_ptr<rappor::Sample> ResourceReporter::CreateRapporSample( | 256 std::unique_ptr<rappor::Sample> ResourceReporter::CreateRapporSample( |
| 254 rappor::RapporService* rappor_service, | 257 rappor::RapporService* rappor_service, |
| 255 const ResourceReporter::TaskRecord& task_record) { | 258 const ResourceReporter::TaskRecord& task_record) { |
| 256 std::unique_ptr<rappor::Sample> sample( | 259 std::unique_ptr<rappor::Sample> sample( |
| 257 rappor_service->CreateSample(rappor::UMA_RAPPOR_TYPE)); | 260 rappor_service->CreateSample(rappor::UMA_RAPPOR_TYPE)); |
| 258 sample->SetStringField(kRapporTaskStringField, | 261 sample->SetStringField(kRapporTaskStringField, |
| 259 task_record.task_name_for_rappor); | 262 task_record.task_name_for_rappor); |
| 260 sample->SetFlagsField(kRapporPriorityFlagsField, | 263 sample->SetFlagsField(kRapporPriorityFlagsField, |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 sampled_task = task_data; | 352 sampled_task = task_data; |
| 350 } | 353 } |
| 351 memory_weights_sum += task_data->memory_bytes; | 354 memory_weights_sum += task_data->memory_bytes; |
| 352 } | 355 } |
| 353 | 356 |
| 354 return sampled_task; | 357 return sampled_task; |
| 355 } | 358 } |
| 356 | 359 |
| 357 void ResourceReporter::OnMemoryPressure( | 360 void ResourceReporter::OnMemoryPressure( |
| 358 MemoryPressureLevel memory_pressure_level) { | 361 MemoryPressureLevel memory_pressure_level) { |
| 359 if (have_seen_first_task_manager_refresh_ && | 362 if (memory_pressure_level == |
| 360 memory_pressure_level == | |
| 361 MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL) { | 363 MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL) { |
| 362 // Report browser and GPU processes usage using UMA histograms. | 364 RecordCurrentState(); |
| 363 UMA_HISTOGRAM_ENUMERATION( | |
| 364 "ResourceReporter.BrowserProcess.CpuUsage", | |
| 365 GET_ENUM_VAL(GetCpuUsageRange(last_browser_process_cpu_)), | |
| 366 GET_ENUM_VAL(CpuUsageRange::NUM_RANGES)); | |
| 367 UMA_HISTOGRAM_ENUMERATION( | |
| 368 "ResourceReporter.BrowserProcess.MemoryUsage", | |
| 369 GET_ENUM_VAL(GetMemoryUsageRange(last_browser_process_memory_)), | |
| 370 GET_ENUM_VAL(MemoryUsageRange::NUM_RANGES)); | |
| 371 UMA_HISTOGRAM_ENUMERATION( | |
| 372 "ResourceReporter.GpuProcess.CpuUsage", | |
| 373 GET_ENUM_VAL(GetCpuUsageRange(last_gpu_process_cpu_)), | |
| 374 GET_ENUM_VAL(CpuUsageRange::NUM_RANGES)); | |
| 375 UMA_HISTOGRAM_ENUMERATION( | |
| 376 "ResourceReporter.GpuProcess.MemoryUsage", | |
| 377 GET_ENUM_VAL(GetMemoryUsageRange(last_gpu_process_memory_)), | |
| 378 GET_ENUM_VAL(MemoryUsageRange::NUM_RANGES)); | |
| 379 | |
| 380 // For the rest of tasks, report them using Rappor. | |
| 381 auto* rappor_service = g_browser_process->rappor_service(); | |
| 382 if (!rappor_service) | |
| 383 return; | |
| 384 | |
| 385 // We only record Rappor samples only if it's the first ever critical memory | |
| 386 // pressure event we receive, or it has been more than | |
| 387 // |kMinimumTimeBetweenReportsInMs| since the last time we recorded samples. | |
| 388 if (!have_seen_first_memory_pressure_event_) { | |
| 389 have_seen_first_memory_pressure_event_ = true; | |
| 390 } else if ((base::TimeTicks::Now() - last_memory_pressure_event_time_) < | |
| 391 base::TimeDelta::FromMilliseconds(kMinimumTimeBetweenReportsInMs)) { | |
| 392 return; | |
| 393 } | |
| 394 | |
| 395 last_memory_pressure_event_time_ = base::TimeTicks::Now(); | |
| 396 | |
| 397 // Use weighted random sampling to select a task to report in the CPU | |
| 398 // metric. | |
| 399 const TaskRecord* sampled_cpu_task = SampleTaskByCpu(); | |
| 400 if (sampled_cpu_task) { | |
| 401 std::unique_ptr<rappor::Sample> cpu_sample( | |
| 402 CreateRapporSample(rappor_service, *sampled_cpu_task)); | |
| 403 cpu_sample->SetFlagsField(kRapporNumCoresRangeFlagsField, | |
| 404 GET_ENUM_VAL(system_cpu_cores_range_), | |
| 405 GET_ENUM_VAL(CpuCoresNumberRange::NUM_RANGES)); | |
| 406 cpu_sample->SetFlagsField( | |
| 407 kRapporUsageRangeFlagsField, | |
| 408 GET_ENUM_VAL(GetCpuUsageRange(sampled_cpu_task->cpu_percent)), | |
| 409 GET_ENUM_VAL(CpuUsageRange::NUM_RANGES)); | |
| 410 rappor_service->RecordSampleObj(kCpuRapporMetric, std::move(cpu_sample)); | |
| 411 } | |
| 412 | |
| 413 // Use weighted random sampling to select a task to report in the memory | |
| 414 // metric. | |
| 415 const TaskRecord* sampled_memory_task = SampleTaskByMemory(); | |
| 416 if (sampled_memory_task) { | |
| 417 std::unique_ptr<rappor::Sample> memory_sample( | |
| 418 CreateRapporSample(rappor_service, *sampled_memory_task)); | |
| 419 memory_sample->SetFlagsField( | |
| 420 kRapporUsageRangeFlagsField, | |
| 421 GET_ENUM_VAL(GetMemoryUsageRange(sampled_memory_task->memory_bytes)), | |
| 422 GET_ENUM_VAL(MemoryUsageRange::NUM_RANGES)); | |
| 423 rappor_service->RecordSampleObj(kMemoryRapporMetric, | |
| 424 std::move(memory_sample)); | |
| 425 } | |
| 426 } | 365 } |
| 427 } | 366 } |
| 428 | 367 |
| 368 void ResourceReporter::OnMemoryStateChange(base::MemoryState state) { | |
| 369 // TODO(hajimehoshi): Adjust the size of this memory usage according to | |
| 370 // |state|. ResourceReporter doesn't have a feature to limit memory usage at | |
| 371 // present. | |
| 372 switch (state) { | |
| 373 case base::MemoryState::NORMAL: | |
| 374 break; | |
| 375 case base::MemoryState::THROTTLED: | |
| 376 RecordCurrentState(); | |
|
bashi
2016/10/04 10:12:20
If I remember the thread we've discussed this migr
hajimehoshi
2016/10/18 10:13:45
The situation has been changed by https://coderevi
| |
| 377 break; | |
| 378 case base::MemoryState::SUSPENDED: | |
| 379 // Note: Not supported at present. Fall through. | |
| 380 case base::MemoryState::UNKNOWN: | |
| 381 NOTREACHED(); | |
| 382 break; | |
| 383 } | |
| 384 } | |
| 385 | |
| 386 void ResourceReporter::RecordCurrentState() { | |
| 387 if (!have_seen_first_task_manager_refresh_) | |
| 388 return; | |
| 389 | |
| 390 // Report browser and GPU processes usage using UMA histograms. | |
| 391 UMA_HISTOGRAM_ENUMERATION( | |
| 392 "ResourceReporter.BrowserProcess.CpuUsage", | |
| 393 GET_ENUM_VAL(GetCpuUsageRange(last_browser_process_cpu_)), | |
| 394 GET_ENUM_VAL(CpuUsageRange::NUM_RANGES)); | |
| 395 UMA_HISTOGRAM_ENUMERATION( | |
| 396 "ResourceReporter.BrowserProcess.MemoryUsage", | |
| 397 GET_ENUM_VAL(GetMemoryUsageRange(last_browser_process_memory_)), | |
| 398 GET_ENUM_VAL(MemoryUsageRange::NUM_RANGES)); | |
| 399 UMA_HISTOGRAM_ENUMERATION( | |
| 400 "ResourceReporter.GpuProcess.CpuUsage", | |
| 401 GET_ENUM_VAL(GetCpuUsageRange(last_gpu_process_cpu_)), | |
| 402 GET_ENUM_VAL(CpuUsageRange::NUM_RANGES)); | |
| 403 UMA_HISTOGRAM_ENUMERATION( | |
| 404 "ResourceReporter.GpuProcess.MemoryUsage", | |
| 405 GET_ENUM_VAL(GetMemoryUsageRange(last_gpu_process_memory_)), | |
| 406 GET_ENUM_VAL(MemoryUsageRange::NUM_RANGES)); | |
| 407 | |
| 408 // For the rest of tasks, report them using Rappor. | |
| 409 auto* rappor_service = g_browser_process->rappor_service(); | |
| 410 if (!rappor_service) | |
| 411 return; | |
| 412 | |
| 413 // We only record Rappor samples only if it's the first ever critical memory | |
| 414 // pressure event we receive, or it has been more than | |
| 415 // |kMinimumTimeBetweenReportsInMs| since the last time we recorded samples. | |
| 416 if (!have_seen_first_memory_pressure_event_) { | |
| 417 have_seen_first_memory_pressure_event_ = true; | |
| 418 } else if ((base::TimeTicks::Now() - last_memory_pressure_event_time_) < | |
| 419 base::TimeDelta::FromMilliseconds( | |
| 420 kMinimumTimeBetweenReportsInMs)) { | |
| 421 return; | |
| 422 } | |
| 423 | |
| 424 last_memory_pressure_event_time_ = base::TimeTicks::Now(); | |
| 425 | |
| 426 // Use weighted random sampling to select a task to report in the CPU | |
| 427 // metric. | |
| 428 const TaskRecord* sampled_cpu_task = SampleTaskByCpu(); | |
| 429 if (sampled_cpu_task) { | |
| 430 std::unique_ptr<rappor::Sample> cpu_sample( | |
| 431 CreateRapporSample(rappor_service, *sampled_cpu_task)); | |
| 432 cpu_sample->SetFlagsField(kRapporNumCoresRangeFlagsField, | |
| 433 GET_ENUM_VAL(system_cpu_cores_range_), | |
| 434 GET_ENUM_VAL(CpuCoresNumberRange::NUM_RANGES)); | |
| 435 cpu_sample->SetFlagsField( | |
| 436 kRapporUsageRangeFlagsField, | |
| 437 GET_ENUM_VAL(GetCpuUsageRange(sampled_cpu_task->cpu_percent)), | |
| 438 GET_ENUM_VAL(CpuUsageRange::NUM_RANGES)); | |
| 439 rappor_service->RecordSampleObj(kCpuRapporMetric, std::move(cpu_sample)); | |
| 440 } | |
| 441 | |
| 442 // Use weighted random sampling to select a task to report in the memory | |
| 443 // metric. | |
| 444 const TaskRecord* sampled_memory_task = SampleTaskByMemory(); | |
| 445 if (sampled_memory_task) { | |
| 446 std::unique_ptr<rappor::Sample> memory_sample( | |
| 447 CreateRapporSample(rappor_service, *sampled_memory_task)); | |
| 448 memory_sample->SetFlagsField( | |
| 449 kRapporUsageRangeFlagsField, | |
| 450 GET_ENUM_VAL(GetMemoryUsageRange(sampled_memory_task->memory_bytes)), | |
| 451 GET_ENUM_VAL(MemoryUsageRange::NUM_RANGES)); | |
| 452 rappor_service->RecordSampleObj(kMemoryRapporMetric, | |
| 453 std::move(memory_sample)); | |
| 454 } | |
| 455 } | |
| 456 | |
| 429 } // namespace chromeos | 457 } // namespace chromeos |
| OLD | NEW |