MediaMetrics: Tune garbage collection
Reduce thresholds for garbage collection.
Track the number of gcs in the dumpsys.
Test: 30x repeated invocation of AudioTrackTest
Test: adb shell showmap '$(pgrep -f audioserver)'
Test: adb shell dumpsys media.metrics --all
Bug: 159410113
Change-Id: I3ff7bb84bc45e44fe3d5ea84fecdf05c76cf5733
diff --git a/services/mediametrics/AnalyticsState.h b/services/mediametrics/AnalyticsState.h
index b648947..09c0b4c 100644
--- a/services/mediametrics/AnalyticsState.h
+++ b/services/mediametrics/AnalyticsState.h
@@ -93,7 +93,7 @@
int32_t ll = lines;
if (ll > 0) {
- ss << "TransactionLog:\n";
+ ss << "TransactionLog: gc(" << mTransactionLog.getGarbageCollectionCount() << ")\n";
--ll;
}
if (ll > 0) {
@@ -102,7 +102,7 @@
ll -= l;
}
if (ll > 0) {
- ss << "TimeMachine:\n";
+ ss << "TimeMachine: gc(" << mTimeMachine.getGarbageCollectionCount() << ")\n";
--ll;
}
if (ll > 0) {
diff --git a/services/mediametrics/TimeMachine.h b/services/mediametrics/TimeMachine.h
index 00a44a4..ce579b3 100644
--- a/services/mediametrics/TimeMachine.h
+++ b/services/mediametrics/TimeMachine.h
@@ -220,10 +220,10 @@
using History = std::map<std::string /* key */, std::shared_ptr<KeyHistory>>;
- static inline constexpr size_t kTimeSequenceMaxElements = 100;
- static inline constexpr size_t kKeyMaxProperties = 100;
- static inline constexpr size_t kKeyLowWaterMark = 500;
- static inline constexpr size_t kKeyHighWaterMark = 1000;
+ static inline constexpr size_t kTimeSequenceMaxElements = 50;
+ static inline constexpr size_t kKeyMaxProperties = 50;
+ static inline constexpr size_t kKeyLowWaterMark = 400;
+ static inline constexpr size_t kKeyHighWaterMark = 500;
// Estimated max data space usage is 3KB * kKeyHighWaterMark.
@@ -255,6 +255,7 @@
{
std::lock_guard lock2(other.mLock);
mHistory = other.mHistory;
+ mGarbageCollectionCount = other.mGarbageCollectionCount.load();
}
// Now that we safely have our own shared pointers, let's dup them
@@ -420,6 +421,7 @@
void clear() {
std::lock_guard lock(mLock);
mHistory.clear();
+ mGarbageCollectionCount = 0;
}
/**
@@ -453,6 +455,10 @@
return { ss.str(), lines - ll };
}
+ size_t getGarbageCollectionCount() const {
+ return mGarbageCollectionCount;
+ }
+
private:
// Obtains the lock for a KeyHistory.
@@ -496,8 +502,6 @@
// TODO: something better than this for garbage collection.
if (mHistory.size() < mKeyHighWaterMark) return false;
- ALOGD("%s: garbage collection", __func__);
-
// erase everything explicitly expired.
std::multimap<int64_t, std::string> accessList;
// use a stale vector with precise type to avoid type erasure overhead in garbage
@@ -534,12 +538,16 @@
ALOGD("%s(%zu, %zu): key size:%zu",
__func__, mKeyLowWaterMark, mKeyHighWaterMark,
mHistory.size());
+
+ ++mGarbageCollectionCount;
return true;
}
const size_t mKeyLowWaterMark = kKeyLowWaterMark;
const size_t mKeyHighWaterMark = kKeyHighWaterMark;
+ std::atomic<size_t> mGarbageCollectionCount{};
+
/**
* Locking Strategy
*
diff --git a/services/mediametrics/TransactionLog.h b/services/mediametrics/TransactionLog.h
index 8a22826..0ca4639 100644
--- a/services/mediametrics/TransactionLog.h
+++ b/services/mediametrics/TransactionLog.h
@@ -43,9 +43,9 @@
// Transaction Log between the Low Water Mark and the High Water Mark.
// low water mark
- static inline constexpr size_t kLogItemsLowWater = 5000;
+ static inline constexpr size_t kLogItemsLowWater = 1700;
// high water mark
- static inline constexpr size_t kLogItemsHighWater = 10000;
+ static inline constexpr size_t kLogItemsHighWater = 2000;
// Estimated max data usage is 1KB * kLogItemsHighWater.
@@ -79,6 +79,7 @@
std::lock_guard lock2(other.mLock);
mLog = other.mLog;
mItemMap = other.mItemMap;
+ mGarbageCollectionCount = other.mGarbageCollectionCount.load();
return *this;
}
@@ -181,6 +182,11 @@
std::lock_guard lock(mLock);
mLog.clear();
mItemMap.clear();
+ mGarbageCollectionCount = 0;
+ }
+
+ size_t getGarbageCollectionCount() const {
+ return mGarbageCollectionCount;
}
private:
@@ -216,8 +222,6 @@
bool gc(std::vector<std::any>& garbage) REQUIRES(mLock) {
if (mLog.size() < mHighWaterMark) return false;
- ALOGD("%s: garbage collection", __func__);
-
auto eraseEnd = mLog.begin();
size_t toRemove = mLog.size() - mLowWaterMark;
// remove at least those elements.
@@ -265,6 +269,7 @@
ALOGD("%s(%zu, %zu): log size:%zu item map size:%zu, item map items:%zu",
__func__, mLowWaterMark, mHighWaterMark,
mLog.size(), mItemMap.size(), itemMapCount);
+ ++mGarbageCollectionCount;
return true;
}
@@ -287,6 +292,8 @@
const size_t mLowWaterMark = kLogItemsLowWater;
const size_t mHighWaterMark = kLogItemsHighWater;
+ std::atomic<size_t> mGarbageCollectionCount{};
+
mutable std::mutex mLock;
MapTimeItem mLog GUARDED_BY(mLock);