• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2024 The Android Open Source Project
3--
4-- Licensed under the Apache License, Version 2.0 (the "License");
5-- you may not use this file except in compliance with the License.
6-- You may obtain a copy of the License at
7--
8--     https://www.apache.org/licenses/LICENSE-2.0
9--
10-- Unless required by applicable law or agreed to in writing, software
11-- distributed under the License is distributed on an "AS IS" BASIS,
12-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-- See the License for the specific language governing permissions and
14-- limitations under the License.
15
16INCLUDE PERFETTO MODULE android.memory.heap_graph.dominator_tree;
17
18INCLUDE PERFETTO MODULE graphs.partition;
19
20CREATE PERFETTO FUNCTION _partition_tree_super_root_fn()
21-- The assigned id of the "super root".
22RETURNS LONG AS
23SELECT
24  id + 1
25FROM heap_graph_object
26ORDER BY
27  id DESC
28LIMIT 1;
29
30CREATE PERFETTO FUNCTION _is_libcore_or_array(
31    obj_name STRING
32)
33RETURNS BOOL AS
34SELECT
35  (
36    $obj_name GLOB 'java.*' AND NOT $obj_name GLOB 'java.lang.Class<*>'
37  )
38  OR $obj_name GLOB 'j$.*'
39  OR $obj_name GLOB 'int[[]*'
40  OR $obj_name GLOB 'long[[]*'
41  OR $obj_name GLOB 'byte[[]*'
42  OR $obj_name GLOB 'char[[]*'
43  OR $obj_name GLOB 'short[[]*'
44  OR $obj_name GLOB 'float[[]*'
45  OR $obj_name GLOB 'double[[]*'
46  OR $obj_name GLOB 'boolean[[]*'
47  OR $obj_name GLOB 'android.util.*Array*';
48
49CREATE PERFETTO TABLE _heap_graph_dominator_tree_for_partition AS
50SELECT
51  tree.id,
52  coalesce(tree.idom_id, _partition_tree_super_root_fn()) AS parent_id,
53  obj.type_id AS group_key
54FROM heap_graph_dominator_tree AS tree
55JOIN heap_graph_object AS obj
56  USING (id)
57UNION ALL
58-- provide a single root required by tree partition if heap graph exists.
59SELECT
60  _partition_tree_super_root_fn() AS id,
61  NULL AS parent_id,
62  (
63    SELECT
64      id + 1
65    FROM heap_graph_class
66    ORDER BY
67      id DESC
68    LIMIT 1
69  ) AS group_key
70WHERE
71  _partition_tree_super_root_fn() IS NOT NULL;
72
73CREATE PERFETTO TABLE _heap_object_marked_for_dominated_stats AS
74SELECT
75  id,
76  iif(parent_id IS NULL, 1, 0) AS marked
77FROM tree_structural_partition_by_group!(_heap_graph_dominator_tree_for_partition)
78ORDER BY
79  id;
80
81-- Class-level breakdown of the java heap.
82-- Per type name aggregates the object stats and the dominator tree stats.
83CREATE PERFETTO TABLE android_heap_graph_class_aggregation (
84  -- Process upid
85  upid JOINID(process.id),
86  -- Heap dump timestamp
87  graph_sample_ts TIMESTAMP,
88  -- Class type id
89  type_id LONG,
90  -- Class name (deobfuscated if available)
91  type_name STRING,
92  -- Is type an instance of a libcore object (java.*) or array
93  is_libcore_or_array BOOL,
94  -- Count of class instances
95  obj_count LONG,
96  -- Size of class instances
97  size_bytes LONG,
98  -- Native size of class instances
99  native_size_bytes LONG,
100  -- Count of reachable class instances
101  reachable_obj_count LONG,
102  -- Size of reachable class instances
103  reachable_size_bytes LONG,
104  -- Native size of reachable class instances
105  reachable_native_size_bytes LONG,
106  -- Count of all objects dominated by instances of this class
107  -- Only applies to reachable objects
108  dominated_obj_count LONG,
109  -- Size of all objects dominated by instances of this class
110  -- Only applies to reachable objects
111  dominated_size_bytes LONG,
112  -- Native size of all objects dominated by instances of this class
113  -- Only applies to reachable objects
114  dominated_native_size_bytes LONG
115) AS
116WITH
117  base AS (
118    -- First level aggregation to avoid joining with class for every object
119    SELECT
120      obj.upid,
121      obj.graph_sample_ts,
122      obj.type_id,
123      count(1) AS obj_count,
124      sum(self_size) AS size_bytes,
125      sum(native_size) AS native_size_bytes,
126      sum(iif(obj.reachable, 1, 0)) AS reachable_obj_count,
127      sum(iif(obj.reachable, self_size, 0)) AS reachable_size_bytes,
128      sum(iif(obj.reachable, native_size, 0)) AS reachable_native_size_bytes,
129      sum(iif(marked, dominated_obj_count, 0)) AS dominated_obj_count,
130      sum(iif(marked, dominated_size_bytes, 0)) AS dominated_size_bytes,
131      sum(iif(marked, dominated_native_size_bytes, 0)) AS dominated_native_size_bytes
132    FROM heap_graph_object AS obj
133    -- Left joins to preserve unreachable objects.
134    LEFT JOIN _heap_object_marked_for_dominated_stats
135      USING (id)
136    LEFT JOIN heap_graph_dominator_tree
137      USING (id)
138    GROUP BY
139      1,
140      2,
141      3
142    ORDER BY
143      1,
144      2,
145      3
146  )
147SELECT
148  upid,
149  graph_sample_ts,
150  type_id,
151  coalesce(cls.deobfuscated_name, cls.name) AS type_name,
152  _is_libcore_or_array(coalesce(cls.deobfuscated_name, cls.name)) AS is_libcore_or_array,
153  sum(obj_count) AS obj_count,
154  sum(size_bytes) AS size_bytes,
155  sum(native_size_bytes) AS native_size_bytes,
156  sum(reachable_obj_count) AS reachable_obj_count,
157  sum(reachable_size_bytes) AS reachable_size_bytes,
158  sum(reachable_native_size_bytes) AS reachable_native_size_bytes,
159  sum(dominated_obj_count) AS dominated_obj_count,
160  sum(dominated_size_bytes) AS dominated_size_bytes,
161  sum(dominated_native_size_bytes) AS dominated_native_size_bytes
162FROM base
163JOIN heap_graph_class AS cls
164  ON base.type_id = cls.id
165GROUP BY
166  1,
167  2,
168  3,
169  4,
170  5
171ORDER BY
172  1,
173  2,
174  3,
175  4,
176  5;
177