Commit ee150027 authored by Benoît Lizé's avatar Benoît Lizé Committed by Commit Bot

blink/bindings: Record memory metrics for foreground string parking.

Memory metrics for ParkableStrings are only reported for background
compression. This adds reporting for foreground compression as well, 5 minutes
after a renderer starts tracking its first parkable string.

Bug: 924164
Change-Id: Iac04e86101e132fa9d67c6cfd25b16e2bce89fb9
Reviewed-on: https://chromium-review.googlesource.com/c/1474663Reviewed-by: default avatarBrian White <bcwhite@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Benoit L <lizeb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#633781}
parent 7af418f0
......@@ -51,9 +51,12 @@ class OnPurgeMemoryListener : public GarbageCollected<OnPurgeMemoryListener>,
}
};
using UnparkedMap =
HashMap<StringImpl*, ParkableStringImpl*, PtrHash<StringImpl>>;
using ParkedSet = HashSet<ParkableStringImpl*, PtrHash<ParkableStringImpl>>;
Vector<ParkableStringImpl*> GetUnparkedStrings(
const HashMap<StringImpl*, ParkableStringImpl*, PtrHash<StringImpl>>&
unparked_strings) {
const UnparkedMap& unparked_strings) {
WTF::Vector<ParkableStringImpl*> unparked;
unparked.ReserveCapacity(unparked_strings.size());
for (ParkableStringImpl* str : unparked_strings.Values())
......@@ -62,6 +65,68 @@ Vector<ParkableStringImpl*> GetUnparkedStrings(
return unparked;
}
struct Statistics {
size_t original_size;
size_t uncompressed_size;
size_t compressed_original_size;
size_t compressed_size;
size_t metadata_size;
size_t overhead_size;
size_t total_size;
int64_t savings_size;
};
Statistics ComputeStatistics(const UnparkedMap& unparked,
const ParkedSet& parked) {
Statistics stats = {};
for (ParkableStringImpl* str : unparked.Values()) {
size_t size = str->CharactersSizeInBytes();
stats.original_size += size;
stats.uncompressed_size += size;
stats.metadata_size += sizeof(ParkableStringImpl);
if (str->has_compressed_data())
stats.overhead_size += str->compressed_size();
}
for (ParkableStringImpl* str : parked) {
size_t size = str->CharactersSizeInBytes();
stats.compressed_original_size += size;
stats.original_size += size;
stats.compressed_size += str->compressed_size();
stats.metadata_size += sizeof(ParkableStringImpl);
}
stats.total_size = stats.uncompressed_size + stats.compressed_size +
stats.metadata_size + stats.overhead_size;
size_t memory_footprint = stats.compressed_size + stats.uncompressed_size +
stats.metadata_size + stats.overhead_size;
stats.savings_size =
stats.original_size - static_cast<int64_t>(memory_footprint);
return stats;
}
void RecordMemoryStatistics(const Statistics& stats,
const std::string& suffix) {
base::UmaHistogramCounts100000("Memory.ParkableString.TotalSizeKb" + suffix,
stats.original_size / 1000);
base::UmaHistogramCounts100000(
"Memory.ParkableString.CompressedSizeKb" + suffix,
stats.compressed_size / 1000);
size_t savings = stats.compressed_original_size - stats.compressed_size;
base::UmaHistogramCounts100000("Memory.ParkableString.SavingsKb" + suffix,
savings / 1000);
if (stats.compressed_original_size != 0) {
size_t ratio_percentage =
(100 * stats.compressed_size) / stats.compressed_original_size;
base::UmaHistogramPercentage(
"Memory.ParkableString.CompressionRatio" + suffix, ratio_percentage);
}
}
} // namespace
// static
......@@ -148,41 +213,17 @@ bool ParkableStringManager::OnMemoryDump(
base::trace_event::MemoryAllocatorDump* dump =
pmd->CreateAllocatorDump("parkable_strings");
size_t original_size = 0;
size_t uncompressed_size = 0;
size_t compressed_size = 0;
size_t metadata_size = 0;
size_t overhead_size = 0;
for (ParkableStringImpl* str : unparked_strings_.Values()) {
original_size += str->CharactersSizeInBytes();
uncompressed_size += str->CharactersSizeInBytes();
metadata_size += sizeof(ParkableStringImpl);
if (str->has_compressed_data())
overhead_size += str->compressed_size();
}
for (ParkableStringImpl* str : parked_strings_) {
original_size += str->CharactersSizeInBytes();
compressed_size += str->compressed_size();
metadata_size += sizeof(ParkableStringImpl);
}
Statistics stats = ComputeStatistics(unparked_strings_, parked_strings_);
size_t total_size =
uncompressed_size + compressed_size + metadata_size + overhead_size;
size_t memory_footprint =
compressed_size + uncompressed_size + metadata_size + overhead_size;
dump->AddScalar("size", "bytes", stats.total_size);
dump->AddScalar("original_size", "bytes", stats.original_size);
dump->AddScalar("uncompressed_size", "bytes", stats.uncompressed_size);
dump->AddScalar("compressed_size", "bytes", stats.compressed_size);
dump->AddScalar("metadata_size", "bytes", stats.metadata_size);
dump->AddScalar("overhead_size", "bytes", stats.overhead_size);
// Has to be uint64_t.
size_t savings_size =
original_size > memory_footprint ? original_size - memory_footprint : 0;
dump->AddScalar("size", "bytes", total_size);
dump->AddScalar("original_size", "bytes", original_size);
dump->AddScalar("uncompressed_size", "bytes", uncompressed_size);
dump->AddScalar("compressed_size", "bytes", compressed_size);
dump->AddScalar("metadata_size", "bytes", metadata_size);
dump->AddScalar("overhead_size", "bytes", overhead_size);
dump->AddScalar("savings_size", "bytes", savings_size);
dump->AddScalar("savings_size", "bytes",
stats.savings_size > 0 ? stats.savings_size : 0);
pmd->AddSuballocation(dump->guid(),
WTF::Partitions::kAllocatedObjectPoolName);
......@@ -229,7 +270,7 @@ scoped_refptr<ParkableStringImpl> ParkableStringManager::Add(
DCHECK(task_runner);
task_runner->PostDelayedTask(
FROM_HERE,
base::BindOnce(&ParkableStringManager::RecordUnparkingCpuCost,
base::BindOnce(&ParkableStringManager::RecordStatisticsAfter5Minutes,
base::Unretained(this)),
base::TimeDelta::FromMinutes(5));
has_posted_unparking_time_accounting_task_ = true;
......@@ -342,36 +383,15 @@ void ParkableStringManager::DropStringsWithCompressedDataAndRecordStatistics() {
ParkAllIfRendererBackgrounded(
ParkableStringImpl::ParkingMode::kIfCompressedDataExists);
size_t total_size = 0, total_before_compression_size = 0;
size_t total_compressed_size = 0;
for (ParkableStringImpl* str : parked_strings_) {
size_t size = str->CharactersSizeInBytes();
total_size += size;
total_before_compression_size += size;
total_compressed_size += str->compressed_size();
}
for (ParkableStringImpl* str : unparked_strings_.Values())
total_size += str->CharactersSizeInBytes();
UMA_HISTOGRAM_COUNTS_100000("Memory.ParkableString.TotalSizeKb",
total_size / 1000);
UMA_HISTOGRAM_COUNTS_100000("Memory.ParkableString.CompressedSizeKb",
total_compressed_size / 1000);
size_t savings = total_before_compression_size - total_compressed_size;
UMA_HISTOGRAM_COUNTS_100000("Memory.ParkableString.SavingsKb",
savings / 1000);
if (total_before_compression_size != 0) {
size_t ratio_percentage =
(100 * total_compressed_size) / total_before_compression_size;
UMA_HISTOGRAM_PERCENTAGE("Memory.ParkableString.CompressionRatio",
ratio_percentage);
}
Statistics stats = ComputeStatistics(unparked_strings_, parked_strings_);
RecordMemoryStatistics(stats, "");
}
void ParkableStringManager::RecordUnparkingCpuCost() const {
void ParkableStringManager::RecordStatisticsAfter5Minutes() const {
base::UmaHistogramTimes("Memory.ParkableString.MainThreadTime.5min",
total_unparking_time_);
Statistics stats = ComputeStatistics(unparked_strings_, parked_strings_);
RecordMemoryStatistics(stats, ".5min");
}
void ParkableStringManager::AgeStringsAndPark() {
......
......@@ -83,7 +83,7 @@ class PLATFORM_EXPORT ParkableStringManager {
void ParkAll(ParkableStringImpl::ParkingMode mode);
void ParkAllIfRendererBackgrounded(ParkableStringImpl::ParkingMode mode);
void DropStringsWithCompressedDataAndRecordStatistics();
void RecordUnparkingCpuCost() const;
void RecordStatisticsAfter5Minutes() const;
void AgeStringsAndPark();
void ScheduleAgingTaskIfNeeded();
......
......@@ -916,7 +916,8 @@ TEST_F(ParkableStringForegroundParkingTest, ReportTotalUnparkingTime) {
// Need to make the string really large, otherwise unparking takes less than
// 1ms, and the 0 bucket is populated.
std::vector<char> data(5 * 1000 * 1000, 'a');
const size_t original_size = 5 * 1000 * 1000;
std::vector<char> data(original_size, 'a');
ParkableString parkable(String(data.data(), data.size()).ReleaseImpl());
ParkAndWait(parkable);
......@@ -926,12 +927,25 @@ TEST_F(ParkableStringForegroundParkingTest, ReportTotalUnparkingTime) {
WaitForAging();
CheckOnlyCpuCostTaskRemains();
}
const size_t compressed_size = parkable.Impl()->compressed_size();
scoped_task_environment_.FastForwardUntilNoTasksRemain();
histogram_tester.ExpectTotalCount("Memory.ParkableString.MainThreadTime.5min",
1);
histogram_tester.ExpectBucketCount(
"Memory.ParkableString.MainThreadTime.5min", 0, 0);
histogram_tester.ExpectUniqueSample("Memory.ParkableString.TotalSizeKb.5min",
original_size / 1000, 1);
histogram_tester.ExpectUniqueSample(
"Memory.ParkableString.CompressedSizeKb.5min", compressed_size / 1000, 1);
size_t expected_savings = original_size - compressed_size;
histogram_tester.ExpectUniqueSample("Memory.ParkableString.SavingsKb.5min",
expected_savings / 1000, 1);
histogram_tester.ExpectUniqueSample(
"Memory.ParkableString.CompressionRatio.5min",
100 * compressed_size / original_size, 1);
}
} // namespace blink
......@@ -52890,6 +52890,16 @@ uploading your change for review.
</summary>
</histogram>
<histogram name="Memory.ParkableString.CompressionRatio.5min" units="%"
expires_after="2019-07-31">
<owner>lizeb@chromium.org</owner>
<summary>
Average compression ratio, 100 * compressed_size / initial_size, for all
compressed ParkableStrings. Recorded at the same time as
&quot;Memory.ParkableString.TotalSizeKb.5min&quot;.
</summary>
</histogram>
<histogram name="Memory.ParkableString.Decompression.Latency"
units="microseconds">
<owner>lizeb@chromium.org</owner>
......@@ -52931,6 +52941,15 @@ uploading your change for review.
</summary>
</histogram>
<histogram name="Memory.ParkableString.SavingsKb.5min" units="KB"
expires_after="2019-07-31">
<owner>lizeb@chromium.org</owner>
<summary>
Sum of memory saved by compression, in KB. Recorded at the same time as
&quot;Memory.ParkableString.TotalSizeKb.5min&quot;.
</summary>
</histogram>
<histogram name="Memory.ParkableString.TotalSizeKb" units="KB">
<owner>lizeb@chromium.org</owner>
<summary>
......@@ -52940,6 +52959,16 @@ uploading your change for review.
</summary>
</histogram>
<histogram name="Memory.ParkableString.TotalSizeKb.5min" units="KB"
expires_after="2019-07-31">
<owner>lizeb@chromium.org</owner>
<summary>
Total size of ParkableStrings assuming no compression, in KB. Recorded once,
5 minutes after the first ParkableString is added to a renderer, at the same
time as &quot;Memory.ParkableString.MainThreadTime.5min&quot;.
</summary>
</histogram>
<histogram name="Memory.PepperFlashPlugin" units="KB">
<obsolete>
Deprecated 11/2017. No direct replacement.
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