Commit dde055db authored by Xi Cheng's avatar Xi Cheng Committed by Commit Bot

Cap the number of pending unserialized profiles

This limits the amount of memory used for unserialized profiles that have
been collected but not yet uploaded (e.g. due to being offline).

When the number of unserialized profiles exceeds the cap, serialize the new
ones to save memory.

Code-wise, this CL changes PendingProfiles to maintain two separate vectors
for unserialized profiles and serialized profiles, so that we can retrieve
the count of each kind of profiles immediately. This CL also simplified the
implementation a bit so that struct ProfileState is no longer needed.

Bug: 888716, 851163
Change-Id: I177d51065da04789db8d411af8387e08336c2342
Reviewed-on: https://chromium-review.googlesource.com/c/1250144
Commit-Queue: Xi Cheng <chengx@chromium.org>
Reviewed-by: default avatarIlya Sherman <isherman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595969}
parent 33a8bcf3
......@@ -73,6 +73,99 @@ TEST_F(CallStackProfileMetricsProviderTest,
uma_proto.sampled_profile(0).trigger_event());
}
// Checks that both the unserialized and serialized pending profiles are
// encoded in the session data.
TEST_F(CallStackProfileMetricsProviderTest,
ProvideCurrentSessionDataUnserializedAndSerialized) {
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
// Receive an unserialized profile.
SampledProfile profile;
profile.set_trigger_event(SampledProfile::PROCESS_STARTUP);
CallStackProfileMetricsProvider::ReceiveProfile(base::TimeTicks::Now(),
std::move(profile));
// Receive a serialized profile.
std::string contents;
{
SampledProfile profile;
profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
profile.SerializeToString(&contents);
}
CallStackProfileMetricsProvider::ReceiveSerializedProfile(
base::TimeTicks::Now(), std::move(contents));
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
ASSERT_EQ(2, uma_proto.sampled_profile().size());
EXPECT_EQ(SampledProfile::PROCESS_STARTUP,
uma_proto.sampled_profile(0).trigger_event());
EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION,
uma_proto.sampled_profile(1).trigger_event());
}
// Checks that the unserialized pending profiles whose number exceeds the
// associated cap are still encoded in the session data.
TEST_F(CallStackProfileMetricsProviderTest,
ProvideCurrentSessionDataExceedUnserializedCap) {
// The value must be consistent with that in
// call_stack_profile_metrics_provider.cc so that this test is meaningful.
constexpr int kMaxPendingUnserializedProfiles = 250;
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
// Receive (kMaxPendingUnserializedProfiles + 1) unserialized profiles.
for (int i = 0; i < kMaxPendingUnserializedProfiles + 1; ++i) {
SampledProfile profile;
profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
CallStackProfileMetricsProvider::ReceiveProfile(base::TimeTicks::Now(),
std::move(profile));
}
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
ASSERT_EQ(kMaxPendingUnserializedProfiles + 1,
uma_proto.sampled_profile().size());
for (int i = 0; i < kMaxPendingUnserializedProfiles + 1; ++i) {
EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION,
uma_proto.sampled_profile(i).trigger_event());
}
}
// Checks that the pending profiles above the total cap are dropped therefore
// not encoded in the session data.
TEST_F(CallStackProfileMetricsProviderTest,
ProvideCurrentSessionDataExceedTotalCap) {
// The value must be consistent with that in
// call_stack_profile_metrics_provider.cc so that this test is meaningful.
const int kMaxPendingProfiles = 1250;
CallStackProfileMetricsProvider provider;
provider.OnRecordingEnabled();
// Receive (kMaxPendingProfiles + 1) profiles.
for (int i = 0; i < kMaxPendingProfiles + 1; ++i) {
SampledProfile profile;
profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
CallStackProfileMetricsProvider::ReceiveProfile(base::TimeTicks::Now(),
std::move(profile));
}
ChromeUserMetricsExtension uma_proto;
provider.ProvideCurrentSessionData(&uma_proto);
// Only kMaxPendingProfiles profiles are encoded, with the additional one
// dropped.
ASSERT_EQ(kMaxPendingProfiles, uma_proto.sampled_profile().size());
for (int i = 0; i < kMaxPendingProfiles; ++i) {
EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION,
uma_proto.sampled_profile(i).trigger_event());
}
}
// Checks that the pending profile is provided to ProvideCurrentSessionData
// when collected before CallStackProfileMetricsProvider is instantiated.
TEST_F(CallStackProfileMetricsProviderTest,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment