From 2e635dbac19877f6ec3378c9bad8b8fcb0249c18 Mon Sep 17 00:00:00 2001 From: Lalit Maganti Date: Sat, 19 Oct 2024 02:24:23 +0100 Subject: [PATCH] tp: add summary of heap graph class tree Allows easy querying of the graph. Change-Id: Iba1fd1db7171a2ba00e6e7397898ba70bfc6c44f --- Android.bp | 1 + BUILD | 1 + .../stdlib/android/memory/heap_graph/BUILD.gn | 1 + .../memory/heap_graph/class_summary_tree.sql | 98 +++++++++++++++++++ .../stdlib/android/heap_graph_tests.py | 17 ++++ 5 files changed, 118 insertions(+) create mode 100644 src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/class_summary_tree.sql diff --git a/Android.bp b/Android.bp index 6f2d315369..2449c4f85f 100644 --- a/Android.bp +++ b/Android.bp @@ -13546,6 +13546,7 @@ genrule { "src/trace_processor/perfetto_sql/stdlib/android/io.sql", "src/trace_processor/perfetto_sql/stdlib/android/job_scheduler.sql", "src/trace_processor/perfetto_sql/stdlib/android/memory/dmabuf.sql", + "src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/class_summary_tree.sql", "src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/class_tree.sql", "src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/dominator_class_tree.sql", "src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/dominator_tree.sql", diff --git a/BUILD b/BUILD index ef31a262aa..5289a89fb1 100644 --- a/BUILD +++ b/BUILD @@ -2751,6 +2751,7 @@ perfetto_filegroup( perfetto_filegroup( name = "src_trace_processor_perfetto_sql_stdlib_android_memory_heap_graph_heap_graph", srcs = [ + "src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/class_summary_tree.sql", "src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/class_tree.sql", "src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/dominator_class_tree.sql", "src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/dominator_tree.sql", diff --git a/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/BUILD.gn index 2c86bfe8f7..4ecaeb0823 100644 --- a/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/BUILD.gn +++ b/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/BUILD.gn @@ -16,6 +16,7 @@ import("../../../../../../../gn/perfetto_sql.gni") perfetto_sql_source_set("heap_graph") { sources = [ + "class_summary_tree.sql", "class_tree.sql", "dominator_class_tree.sql", "dominator_tree.sql", diff --git a/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/class_summary_tree.sql b/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/class_summary_tree.sql new file mode 100644 index 0000000000..9c9d5bf283 --- /dev/null +++ b/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/class_summary_tree.sql @@ -0,0 +1,98 @@ +-- +-- Copyright 2024 The Android Open Source Project +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- https://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed ON an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +INCLUDE PERFETTO MODULE android.memory.heap_graph.class_tree; +INCLUDE PERFETTO MODULE graphs.scan; + +CREATE PERFETTO TABLE _heap_graph_class_tree_cumulatives AS +SELECT * +FROM _graph_aggregating_scan!( + ( + SELECT id AS source_node_id, parent_id AS dest_node_id + FROM _heap_graph_class_tree + WHERE parent_id IS NOT NULL + ), + ( + SELECT + p.id, + p.self_count AS cumulative_count, + p.self_size AS cumulative_size + FROM _heap_graph_class_tree p + LEFT JOIN _heap_graph_class_tree c ON c.parent_id = p.id + WHERE c.id IS NULL + ), + (cumulative_count, cumulative_size), + ( + WITH agg AS ( + SELECT + t.id, + SUM(t.cumulative_count) AS child_count, + SUM(t.cumulative_size) AS child_size + FROM $table t + GROUP BY t.id + ) + SELECT + a.id, + a.child_count + r.self_count as cumulative_count, + a.child_size + r.self_size as cumulative_size + FROM agg a + JOIN _heap_graph_class_tree r USING (id) + ) +) a +ORDER BY id; + +-- Table containing all the Android heap graphs in the trace converted to a +-- shortest-path tree and then aggregated by class name. +-- +-- This table contains a "flamegraph-like" representation of the contents of the +-- heap graph. +CREATE PERFETTO TABLE android_heap_graph_class_summary_tree( + -- The timestamp the heap graph was dumped at. + graph_sample_ts INT, + -- The upid of the process. + upid INT, + -- The id of the node in the class tree. + id INT, + -- The parent id of the node in the class tree or NULL if this is the root. + parent_id INT, + -- The name of the class. + name STRING, + -- A string describing the type of Java root if this node is a root or NULL + -- if this node is not a root. + root_type STRING, + -- The count of objects with the same class name and the same path to the + -- root. + self_count INT, + -- The size of objects with the same class name and the same path to the + -- root. + self_size INT, + -- The sum of `self_count` of this node and all descendants of this node. + cumulative_count INT, + -- The sum of `self_size` of this node and all descendants of this node. + cumulative_size INT +) AS +SELECT + t.graph_sample_ts, + t.upid, + t.id, + t.parent_id, + t.name, + t.root_type, + t.self_count, + t.self_size, + c.cumulative_count, + c.cumulative_size +FROM _heap_graph_class_tree t +JOIN _heap_graph_class_tree_cumulatives c USING (id); diff --git a/test/trace_processor/diff_tests/stdlib/android/heap_graph_tests.py b/test/trace_processor/diff_tests/stdlib/android/heap_graph_tests.py index fe3ba2d906..dfe5b2d8e0 100644 --- a/test/trace_processor/diff_tests/stdlib/android/heap_graph_tests.py +++ b/test/trace_processor/diff_tests/stdlib/android/heap_graph_tests.py @@ -84,3 +84,20 @@ def test_heap_graph_aggregation(self): 10,2,"B",0,1,1000,1,1000 10,2,"java.lang.String",1,2,10666,2,10666 """)) + + def test_heap_graph_class_summary_tree(self): + return DiffTestBlueprint( + trace=Path('heap_graph_for_aggregation.textproto'), + query=""" + INCLUDE PERFETTO MODULE android.memory.heap_graph.class_summary_tree; + + SELECT name, self_count, self_size, cumulative_count, cumulative_size + FROM android_heap_graph_class_summary_tree + ORDER BY cumulative_size DESC; + """, + out=Csv(""" + "name","self_count","self_size","cumulative_count","cumulative_size" + "A",2,200,4,11200 + "java.lang.String",1,10000,1,10000 + "B",1,1000,1,1000 + """))