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