• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2019 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--
16
17SELECT RUN_METRIC('android/process_metadata.sql');
18SELECT RUN_METRIC('android/process_mem.sql');
19
20CREATE VIEW java_heap_stats_output AS
21WITH
22-- Base view
23base_stat_counts AS (
24  SELECT
25    upid,
26    graph_sample_ts,
27    SUM(self_size) AS total_size,
28    COUNT(1) AS total_obj_count,
29    SUM(CASE reachable WHEN TRUE THEN self_size ELSE 0 END) AS reachable_size,
30    SUM(CASE reachable WHEN TRUE THEN 1 ELSE 0 END) AS reachable_obj_count
31  FROM heap_graph_object
32  GROUP BY 1, 2
33),
34heap_roots AS (
35  SELECT
36    upid,
37    graph_sample_ts,
38    root_type,
39    IFNULL(t.deobfuscated_name, t.name) type_name,
40    COUNT(1) obj_count
41  FROM heap_graph_object o
42  JOIN heap_graph_class t ON o.type_id = t.id
43  -- Classes are going to be particularly spammy and uninteresting
44  -- from a memory analysis perspective (compared e.g. to local jni roots)
45  WHERE root_type IS NOT NULL AND root_type != 'ROOT_STICKY_CLASS'
46  GROUP BY 1, 2, 3, 4
47  ORDER BY obj_count DESC
48),
49heap_roots_proto AS (
50  SELECT
51    upid,
52    graph_sample_ts,
53    RepeatedField(JavaHeapStats_HeapRoots(
54      'root_type', root_type,
55      'type_name', type_name,
56      'obj_count', obj_count
57    )) roots
58  FROM heap_roots
59  GROUP BY 1, 2
60),
61base_stats AS (
62  SELECT * FROM base_stat_counts JOIN heap_roots_proto USING (upid, graph_sample_ts)
63),
64-- Find closest value
65closest_anon_swap AS (
66  SELECT
67    upid,
68    graph_sample_ts,
69    (
70      SELECT anon_swap_val
71      FROM (
72        SELECT
73          ts, dur,
74          CAST(anon_and_swap_val AS INTEGER) anon_swap_val,
75          ABS(ts - base_stats.graph_sample_ts) diff
76        FROM anon_and_swap_span
77        WHERE upid = base_stats.upid)
78      WHERE
79        (graph_sample_ts >= ts AND graph_sample_ts < ts + dur)
80         -- If the first memory sample for the UPID comes *after* the heap profile
81         -- accept it if close (500ms)
82        OR (graph_sample_ts < ts AND diff <= 500 * 1e6)
83      ORDER BY diff LIMIT 1
84    ) val
85  FROM base_stats
86),
87-- Group by upid
88heap_graph_sample_protos AS (
89  SELECT
90    base_stats.upid,
91    RepeatedField(JavaHeapStats_Sample(
92      'ts', graph_sample_ts,
93      'heap_size', total_size,
94      'obj_count', total_obj_count,
95      'reachable_heap_size', reachable_size,
96      'reachable_obj_count', reachable_obj_count,
97      'roots', roots,
98      'anon_rss_and_swap_size', closest_anon_swap.val
99    )) sample_protos
100  FROM base_stats
101  LEFT JOIN closest_anon_swap USING (upid, graph_sample_ts)
102  GROUP BY 1
103)
104SELECT JavaHeapStats(
105  'instance_stats', RepeatedField(JavaHeapStats_InstanceStats(
106    'upid', upid,
107    'process', process_metadata.metadata,
108    'samples', sample_protos
109  )))
110FROM heap_graph_sample_protos JOIN process_metadata USING (upid);
111