diff options
author | 2016-11-14 17:00:28 -0800 | |
---|---|---|
committer | 2016-11-14 17:22:51 -0800 | |
commit | 6e970e7fa88efd5ee38b0d6f9010a3985c62778f (patch) | |
tree | 00668e815cf5a3298f2355b24bb68b20f0163df0 /runtime/reference_table_test.cc | |
parent | 8f2af0cab9010eac1d29730e50bd021053638d81 (diff) |
ART: Prioritize reference table dump
Sort the reference table summary dump by highest count, prioritizing
repeated types and instances. This will help with triaging leaks.
Add a test.
Bug: 32857749
Test: m test-art-host-gtest-reference_table_test
Change-Id: I7e61881b5badf9ac2b6b72333f31437ab498caee
Diffstat (limited to 'runtime/reference_table_test.cc')
-rw-r--r-- | runtime/reference_table_test.cc | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/runtime/reference_table_test.cc b/runtime/reference_table_test.cc index 489db9aa6c..d80a9b3dd1 100644 --- a/runtime/reference_table_test.cc +++ b/runtime/reference_table_test.cc @@ -166,4 +166,77 @@ TEST_F(ReferenceTableTest, Basics) { } } +static std::vector<size_t> FindAll(const std::string& haystack, const char* needle) { + std::vector<size_t> res; + size_t start = 0; + do { + size_t pos = haystack.find(needle, start); + if (pos == std::string::npos) { + break; + } + res.push_back(pos); + start = pos + 1; + } while (start < haystack.size()); + return res; +} + +TEST_F(ReferenceTableTest, SummaryOrder) { + // Check that the summary statistics are sorted. + ScopedObjectAccess soa(Thread::Current()); + + ReferenceTable rt("test", 0, 20); + + { + mirror::Object* s1 = mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello"); + mirror::Object* s2 = mirror::String::AllocFromModifiedUtf8(soa.Self(), "world"); + + // 3 copies of s1, 2 copies of s2, interleaved. + for (size_t i = 0; i != 2; ++i) { + rt.Add(s1); + rt.Add(s2); + } + rt.Add(s1); + } + + { + // Differently sized byte arrays. Should be sorted by identical (non-unique cound). + mirror::Object* b1_1 = mirror::ByteArray::Alloc(soa.Self(), 1); + rt.Add(b1_1); + rt.Add(mirror::ByteArray::Alloc(soa.Self(), 2)); + rt.Add(b1_1); + rt.Add(mirror::ByteArray::Alloc(soa.Self(), 2)); + rt.Add(mirror::ByteArray::Alloc(soa.Self(), 1)); + rt.Add(mirror::ByteArray::Alloc(soa.Self(), 2)); + } + + rt.Add(mirror::CharArray::Alloc(soa.Self(), 0)); + + // Now dump, and ensure order. + std::ostringstream oss; + rt.Dump(oss); + + // Only do this on the part after Summary. + std::string base = oss.str(); + size_t summary_pos = base.find("Summary:"); + ASSERT_NE(summary_pos, std::string::npos); + + std::string haystack = base.substr(summary_pos); + + std::vector<size_t> strCounts = FindAll(haystack, "java.lang.String"); + std::vector<size_t> b1Counts = FindAll(haystack, "byte[] (1 elements)"); + std::vector<size_t> b2Counts = FindAll(haystack, "byte[] (2 elements)"); + std::vector<size_t> cCounts = FindAll(haystack, "char[]"); + + // Only one each. + EXPECT_EQ(1u, strCounts.size()); + EXPECT_EQ(1u, b1Counts.size()); + EXPECT_EQ(1u, b2Counts.size()); + EXPECT_EQ(1u, cCounts.size()); + + // Expect them to be in order. + EXPECT_LT(strCounts[0], b1Counts[0]); + EXPECT_LT(b1Counts[0], b2Counts[0]); + EXPECT_LT(b2Counts[0], cCounts[0]); +} + } // namespace art |