Add new metrics to report averages as sum and count
This CL will introduce new metrics for reporting separately the sum
(numerator) and count (denominator) of the average metrics currently
defined, as average values (or any non-monotonic metric) currently
cannot be aggregated gracefully as Value Metrics in StatsD.
Test: atest art_standalone_libartbase_tests
Test: atest art_standalone_runtime_tests
Test: ART run-test 2232-write-metrics-to-log
Bug: 229618060
Change-Id: I88741e38b5e9fa784efa57cc9ef079dd7ee4c447
diff --git a/libartbase/base/metrics/metrics.h b/libartbase/base/metrics/metrics.h
index 197d69b..6d856da 100644
--- a/libartbase/base/metrics/metrics.h
+++ b/libartbase/base/metrics/metrics.h
@@ -56,7 +56,15 @@
METRIC(YoungGcThroughput, MetricsHistogram, 15, 0, 10'000) \
METRIC(FullGcThroughput, MetricsHistogram, 15, 0, 10'000) \
METRIC(YoungGcTracingThroughput, MetricsHistogram, 15, 0, 10'000) \
- METRIC(FullGcTracingThroughput, MetricsHistogram, 15, 0, 10'000)
+ METRIC(FullGcTracingThroughput, MetricsHistogram, 15, 0, 10'000) \
+ METRIC(GcWorldStopTime, MetricsCounter) \
+ METRIC(GcWorldStopCount, MetricsCounter) \
+ METRIC(YoungGcScannedBytes, MetricsCounter) \
+ METRIC(YoungGcFreedBytes, MetricsCounter) \
+ METRIC(YoungGcDuration, MetricsCounter) \
+ METRIC(FullGcScannedBytes, MetricsCounter) \
+ METRIC(FullGcFreedBytes, MetricsCounter) \
+ METRIC(FullGcDuration, MetricsCounter)
// A lot of the metrics implementation code is generated by passing one-off macros into ART_COUNTERS
// and ART_HISTOGRAMS. This means metrics.h and metrics.cc are very #define-heavy, which can be
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 0de62fe..f3c61e3 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -164,6 +164,9 @@
gc_tracing_throughput_hist_ = metrics->YoungGcTracingThroughput();
gc_throughput_avg_ = metrics->YoungGcThroughputAvg();
gc_tracing_throughput_avg_ = metrics->YoungGcTracingThroughputAvg();
+ gc_scanned_bytes_ = metrics->YoungGcScannedBytes();
+ gc_freed_bytes_ = metrics->YoungGcFreedBytes();
+ gc_duration_ = metrics->YoungGcDuration();
} else {
gc_time_histogram_ = metrics->FullGcCollectionTime();
metrics_gc_count_ = metrics->FullGcCount();
@@ -171,6 +174,9 @@
gc_tracing_throughput_hist_ = metrics->FullGcTracingThroughput();
gc_throughput_avg_ = metrics->FullGcThroughputAvg();
gc_tracing_throughput_avg_ = metrics->FullGcTracingThroughputAvg();
+ gc_scanned_bytes_ = metrics->FullGcScannedBytes();
+ gc_freed_bytes_ = metrics->FullGcFreedBytes();
+ gc_duration_ = metrics->FullGcDuration();
}
}
diff --git a/runtime/gc/collector/garbage_collector.cc b/runtime/gc/collector/garbage_collector.cc
index 80b3982..4efe48c 100644
--- a/runtime/gc/collector/garbage_collector.cc
+++ b/runtime/gc/collector/garbage_collector.cc
@@ -76,6 +76,9 @@
gc_tracing_throughput_hist_(nullptr),
gc_throughput_avg_(nullptr),
gc_tracing_throughput_avg_(nullptr),
+ gc_scanned_bytes_(nullptr),
+ gc_freed_bytes_(nullptr),
+ gc_duration_(nullptr),
cumulative_timings_(name),
pause_histogram_lock_("pause histogram lock", kDefaultMutexLevel, true),
is_transaction_active_(false),
@@ -189,15 +192,18 @@
RegisterPause(duration_ns);
}
total_time_ns_ += duration_ns;
- uint64_t total_pause_time = 0;
+ uint64_t total_pause_time_ns = 0;
for (uint64_t pause_time : current_iteration->GetPauseTimes()) {
MutexLock mu(self, pause_histogram_lock_);
pause_histogram_.AdjustAndAddValue(pause_time);
- total_pause_time += pause_time;
+ total_pause_time_ns += pause_time;
}
metrics::ArtMetrics* metrics = runtime->GetMetrics();
// Report STW pause time in microseconds.
- metrics->WorldStopTimeDuringGCAvg()->Add(total_pause_time / 1'000);
+ const uint64_t total_pause_time_us = total_pause_time_ns / 1'000;
+ metrics->WorldStopTimeDuringGCAvg()->Add(total_pause_time_us);
+ metrics->GcWorldStopTime()->Add(total_pause_time_us);
+ metrics->GcWorldStopCount()->AddOne();
// Report total collection time of all GCs put together.
metrics->TotalGcCollectionTime()->Add(NsToMs(duration_ns));
if (are_metrics_initialized_) {
@@ -216,6 +222,10 @@
throughput = current_iteration->GetEstimatedThroughput() / MB;
gc_throughput_histogram_->Add(throughput);
gc_throughput_avg_->Add(throughput);
+
+ gc_scanned_bytes_->Add(current_iteration->GetScannedBytes());
+ gc_freed_bytes_->Add(current_iteration->GetFreedBytes());
+ gc_duration_->Add(NsToMs(current_iteration->GetDurationNs()));
}
is_transaction_active_ = false;
}
diff --git a/runtime/gc/collector/garbage_collector.h b/runtime/gc/collector/garbage_collector.h
index d439914..d11aea3 100644
--- a/runtime/gc/collector/garbage_collector.h
+++ b/runtime/gc/collector/garbage_collector.h
@@ -166,6 +166,9 @@
metrics::MetricsBase<int64_t>* gc_tracing_throughput_hist_;
metrics::MetricsBase<uint64_t>* gc_throughput_avg_;
metrics::MetricsBase<uint64_t>* gc_tracing_throughput_avg_;
+ metrics::MetricsBase<uint64_t>* gc_scanned_bytes_;
+ metrics::MetricsBase<uint64_t>* gc_freed_bytes_;
+ metrics::MetricsBase<uint64_t>* gc_duration_;
uint64_t total_thread_cpu_time_ns_;
uint64_t total_time_ns_;
uint64_t total_freed_objects_;
diff --git a/runtime/metrics/statsd.cc b/runtime/metrics/statsd.cc
index f68d507..560e7da 100644
--- a/runtime/metrics/statsd.cc
+++ b/runtime/metrics/statsd.cc
@@ -106,6 +106,30 @@
case DatumId::kFullGcTracingThroughputAvg:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_TRACING_THROUGHPUT_AVG_MB_PER_SEC);
+ case DatumId::kGcWorldStopTime:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_WORLD_STOP_TIME_US);
+ case DatumId::kGcWorldStopCount:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_WORLD_STOP_COUNT);
+ case DatumId::kYoungGcScannedBytes:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_SCANNED_BYTES);
+ case DatumId::kYoungGcFreedBytes:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_FREED_BYTES);
+ case DatumId::kYoungGcDuration:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_DURATION_MS);
+ case DatumId::kFullGcScannedBytes:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_SCANNED_BYTES);
+ case DatumId::kFullGcFreedBytes:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_FREED_BYTES);
+ case DatumId::kFullGcDuration:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_DURATION_MS);
}
}