• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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  *      http://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 
17 package com.android.server.am.compaction;
18 
19 import dalvik.annotation.optimization.NeverCompile;
20 
21 import java.io.PrintWriter;
22 
23 class AggregatedCompactionStats {
24     // Throttling stats
25     public long mFullCompactRequested;
26     public long mSomeCompactRequested;
27     public long mFullCompactPerformed;
28     public long mSomeCompactPerformed;
29     public long mProcCompactionsNoPidThrottled;
30     public long mProcCompactionsOomAdjThrottled;
31     public long mProcCompactionsTimeThrottled;
32     public long mProcCompactionsRSSThrottled;
33     public long mProcCompactionsMiscThrottled;
34 
35     // Memory stats
36     public long mTotalDeltaAnonRssKBs;
37     public long mTotalZramConsumedKBs;
38     public long mTotalAnonMemFreedKBs;
39     public long mSumOrigAnonRss;
40     public double mMaxCompactEfficiency;
41     public double mMaxSwapEfficiency;
42 
43     // Cpu time
44     public long mTotalCpuTimeMillis;
45 
getThrottledSome()46     public long getThrottledSome() { return mSomeCompactRequested - mSomeCompactPerformed; }
47 
getThrottledFull()48     public long getThrottledFull() { return mFullCompactRequested - mFullCompactPerformed; }
49 
addMemStats(long anonRssSaved, long zramConsumed, long memFreed, long origAnonRss, long totalCpuTimeMillis)50     public void addMemStats(long anonRssSaved, long zramConsumed, long memFreed,
51             long origAnonRss, long totalCpuTimeMillis) {
52         final double compactEfficiency = memFreed / (double) origAnonRss;
53         if (compactEfficiency > mMaxCompactEfficiency) {
54             mMaxCompactEfficiency = compactEfficiency;
55         }
56         final double swapEfficiency = anonRssSaved / (double) origAnonRss;
57         if (swapEfficiency > mMaxSwapEfficiency) {
58             mMaxSwapEfficiency = swapEfficiency;
59         }
60         mTotalDeltaAnonRssKBs += anonRssSaved;
61         mTotalZramConsumedKBs += zramConsumed;
62         mTotalAnonMemFreedKBs += memFreed;
63         mSumOrigAnonRss += origAnonRss;
64         mTotalCpuTimeMillis += totalCpuTimeMillis;
65     }
66 
67     @NeverCompile
dump(PrintWriter pw)68     public void dump(PrintWriter pw) {
69         long totalCompactRequested = mSomeCompactRequested + mFullCompactRequested;
70         long totalCompactPerformed = mSomeCompactPerformed + mFullCompactPerformed;
71         pw.println("    Performed / Requested:");
72         pw.println("      Some: (" + mSomeCompactPerformed + "/" + mSomeCompactRequested + ")");
73         pw.println("      Full: (" + mFullCompactPerformed + "/" + mFullCompactRequested + ")");
74 
75         long throttledSome = getThrottledSome();
76         long throttledFull = getThrottledFull();
77 
78         if (throttledSome > 0 || throttledFull > 0) {
79             pw.println("    Throttled:");
80             pw.println("       Some: " + throttledSome + " Full: " + throttledFull);
81             pw.println("    Throttled by Type:");
82             final long compactionsThrottled = totalCompactRequested - totalCompactPerformed;
83             // Any throttle that was not part of the previous categories
84             final long unaccountedThrottled = compactionsThrottled
85                     - mProcCompactionsNoPidThrottled - mProcCompactionsOomAdjThrottled
86                     - mProcCompactionsTimeThrottled - mProcCompactionsRSSThrottled
87                     - mProcCompactionsMiscThrottled;
88             pw.println("       NoPid: " + mProcCompactionsNoPidThrottled
89                     + " OomAdj: " + mProcCompactionsOomAdjThrottled + " Time: "
90                     + mProcCompactionsTimeThrottled + " RSS: " + mProcCompactionsRSSThrottled
91                     + " Misc: " + mProcCompactionsMiscThrottled
92                     + " Unaccounted: " + unaccountedThrottled);
93             final double compactThrottlePercentage =
94                     (compactionsThrottled / (double) totalCompactRequested) * 100.0;
95             pw.println("    Throttle Percentage: " + compactThrottlePercentage);
96         }
97 
98         if (mFullCompactPerformed > 0) {
99             pw.println("    -----Memory Stats----");
100             pw.println("    Total Delta Anon RSS (KB) : " + mTotalDeltaAnonRssKBs);
101             pw.println("    Total Physical ZRAM Consumed (KB): " + mTotalZramConsumedKBs);
102             // Anon Mem Freed = Delta Anon RSS - ZRAM Consumed
103             pw.println("    Total Anon Memory Freed (KB): " + mTotalAnonMemFreedKBs);
104             pw.println("    Avg Swap Efficiency (KB) (Delta Anon RSS/Orig Anon RSS): "
105                     + (mTotalDeltaAnonRssKBs / (double) mSumOrigAnonRss));
106             pw.println("    Max Swap Efficiency: " + mMaxSwapEfficiency);
107             // This tells us how much anon memory we were able to free thanks to running
108             // compaction
109             pw.println("    Avg Compaction Efficiency (Anon Freed/Anon RSS): "
110                     + (mTotalAnonMemFreedKBs / (double) mSumOrigAnonRss));
111             pw.println("    Max Compaction Efficiency: " + mMaxCompactEfficiency);
112             // This tells us how effective is the compression algorithm in physical memory
113             pw.println("    Avg Compression Ratio (1 - ZRAM Consumed/DeltaAnonRSS): "
114                     + (1.0 - mTotalZramConsumedKBs / (double) mTotalDeltaAnonRssKBs));
115             long avgKBsPerProcCompact = mFullCompactPerformed > 0
116                     ? (mTotalAnonMemFreedKBs / mFullCompactPerformed)
117                     : 0;
118             pw.println("    Avg Anon Mem Freed/Compaction (KB) : " + avgKBsPerProcCompact);
119             double compactionCost =
120                     mTotalCpuTimeMillis / (mTotalAnonMemFreedKBs / 1024.0); // ms/MB
121             pw.println("    Compaction Cost (ms/MB): " + compactionCost);
122         }
123     }
124 }
125