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

Unified Diff: components/memory_pressure/memory_pressure_stats_collector.cc

Issue 1310043004: Create MemoryPressureStatsCollector. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: components/memory_pressure/memory_pressure_stats_collector.cc
diff --git a/components/memory_pressure/memory_pressure_stats_collector.cc b/components/memory_pressure/memory_pressure_stats_collector.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e068665ee1e210eee4bdea28df99265a37b306de
--- /dev/null
+++ b/components/memory_pressure/memory_pressure_stats_collector.cc
@@ -0,0 +1,173 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/memory_pressure/memory_pressure_stats_collector.h"
+
+#include "base/metrics/histogram.h"
+#include "base/time/default_tick_clock.h"
+
+namespace memory_pressure {
+
+namespace {
+
+using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel;
+
+// A special memory pressure level that is used to indicate that the stats
+// collector has not yet been called.
+const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_INVALID =
+ static_cast<MemoryPressureLevel>(
+ MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE - 1);
+
+// Converts a memory pressure level to an UMA enumeration value.
+MemoryPressureLevelUMA MemoryPressureLevelToUmaEnumValue(
+ MemoryPressureLevel level) {
+ switch (level) {
+ case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
+ return UMA_MEMORY_PRESSURE_LEVEL_NONE;
+ case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
+ return UMA_MEMORY_PRESSURE_LEVEL_MODERATE;
+ case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
+ return UMA_MEMORY_PRESSURE_LEVEL_CRITICAL;
+ }
+ NOTREACHED();
+ return UMA_MEMORY_PRESSURE_LEVEL_COUNT;
+}
+
+// Converts an UMA enumeration value to a memory pressure level.
+MemoryPressureLevel MemoryPressureLevelFromUmaEnumValue(
+ MemoryPressureLevelUMA level) {
+ switch (level) {
+ case UMA_MEMORY_PRESSURE_LEVEL_NONE:
+ return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
+ case UMA_MEMORY_PRESSURE_LEVEL_MODERATE:
+ return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
+ case UMA_MEMORY_PRESSURE_LEVEL_CRITICAL:
+ return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
+ }
+ NOTREACHED();
+ return MEMORY_PRESSURE_LEVEL_INVALID;
+}
+
+} // namespace
+
+MemoryPressureStatsCollector::MemoryPressureStatsCollector()
+ : reporting_delegate_(new UmaReportingDelegate()),
+ tick_clock_(new base::DefaultTickClock()),
+ last_pressure_level_(MEMORY_PRESSURE_LEVEL_INVALID) {}
+
+void MemoryPressureStatsCollector::UpdateStatistics(
+ MemoryPressureLevel current_pressure_level) {
+ base::TimeTicks now = tick_clock_->NowTicks();
+
+ // Special case: first call to the collector. Observations have just started
+ // so there's nothing to report.
+ if (last_pressure_level_ == MEMORY_PRESSURE_LEVEL_INVALID) {
+ last_pressure_level_ = current_pressure_level;
+ last_update_time_ = now;
+ return;
+ }
+
+ // If the pressure level has transitioned then report this.
+ if (last_pressure_level_ != current_pressure_level) {
+ reporting_delegate_->ReportLevelChange(last_pressure_level_,
+ current_pressure_level);
+ }
+
+ // Increment the appropriate cumulative bucket.
+ int index = MemoryPressureLevelToUmaEnumValue(current_pressure_level);
+ base::TimeDelta time_since_update = now - last_update_time_;
+ unreported_cumulative_time_[index] += time_since_update;
+
+ // Update last pressure related state.
+ last_pressure_level_ = current_pressure_level;
+ last_update_time_ = now;
+
+ // Make reports about the amount of time spent cumulatively at each level.
+ for (size_t i = 0; i < arraysize(unreported_cumulative_time_); ++i) {
+ if (unreported_cumulative_time_[i].is_zero())
+ continue;
+ reporting_delegate_->ReportCumulativeTime(
+ MemoryPressureLevelFromUmaEnumValue(
+ static_cast<MemoryPressureLevelUMA>(i)),
+ &unreported_cumulative_time_[i]);
+ }
+}
+
+namespace {
+
+// Enumeration of UMA pressure level changes. This needs to be kept in sync
+// with histograms.xml and the memory pressure levels defined in
+// MemoryPressureListener.
+enum MemoryPressureLevelChangeUMA {
+ UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE = 0,
+ UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_CRITICAL = 1,
+ UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_CRITICAL = 2,
+ UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE = 3,
+ UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_NONE = 4,
+ UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_NONE = 5,
+ // This must be the last value in the enum.
+ UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT
+};
+
+// Converts a pressure state change to an UMA enumeration value.
+MemoryPressureLevelChangeUMA MemoryPressureLevelChangeToUmaEnumValue(
+ MemoryPressureLevel old_level,
+ MemoryPressureLevel new_level) {
+ switch (old_level) {
+ case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: {
+ if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE)
+ return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE;
+ if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
+ return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_CRITICAL;
+ }
+ case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: {
+ if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
+ return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_NONE;
+ if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
+ return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_CRITICAL;
+ }
+ case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: {
+ if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
+ return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE;
+ if (new_level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE)
+ return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE;
+ }
+ }
+ NOTREACHED();
+ return UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT;
+}
+
+} // namespace
+
+void MemoryPressureStatsCollector::UmaReportingDelegate::ReportCumulativeTime(
+ MemoryPressureLevel pressure_level,
+ base::TimeDelta* time) {
+ // Extract the number of seconds and leave behind the milliseconds.
+ int64 seconds = time->InSeconds();
+ *time -= base::TimeDelta::FromSeconds(seconds);
+
+ // Increment the histogram for each second spent in the given state.
+ for (int64 i = 0; i < seconds; ++i) {
+ UMA_HISTOGRAM_ENUMERATION("Memory.PressureLevel",
rkaplow 2015/09/03 17:22:36 alexei - is there a more efficient way to add N en
rkaplow 2015/09/03 17:22:36 We're already writing to this in other places eg.
chrisha 2015/09/03 20:00:45 Turns out there is now! AddCount! But it's not exp
chrisha 2015/09/03 20:00:45 No interaction at all. This component will replace
rkaplow 2015/09/03 22:15:07 Agreed. This is fine for now. Maybe add a TODO to
rkaplow 2015/09/03 22:15:07 AH right - missed that this wasn't hooked up yet.
+ MemoryPressureLevelToUmaEnumValue(pressure_level),
+ UMA_MEMORY_PRESSURE_LEVEL_COUNT);
+#if defined(OS_CHROMEOS)
+ // Continue to emit the old metric on ChromeOS during the transition period.
rkaplow 2015/09/03 17:22:36 describe a little more maybe how this is transitio
chrisha 2015/09/03 20:00:45 Actually, I've rethought this. When I switch to us
rkaplow 2015/09/03 22:15:07 that sounds good.
+ UMA_HISTOGRAM_ENUMERATION("ChromeOS.MemoryPressureLevel",
+ MemoryPressureLevelToUmaEnumValue(pressure_level),
+ UMA_MEMORY_PRESSURE_LEVEL_COUNT);
+#endif
+ }
+}
+
+void MemoryPressureStatsCollector::UmaReportingDelegate::ReportLevelChange(
+ MemoryPressureLevel old_pressure_level,
+ MemoryPressureLevel new_pressure_level) {
+ UMA_HISTOGRAM_ENUMERATION("Memory.PressureLevelChange",
+ MemoryPressureLevelChangeToUmaEnumValue(
+ old_pressure_level, new_pressure_level),
+ UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT);
+}
+
+} // namespace memory_pressure

Powered by Google App Engine
This is Rietveld 408576698