165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/* 265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2010 The Android Open Source Project 365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License"); 565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License. 665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at 765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * http://www.apache.org/licenses/LICENSE-2.0 965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software 1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS, 1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and 1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License. 1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpackage dalvik.system.profiler; 1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.io.IOException; 2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.io.OutputStream; 2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.io.PrintWriter; 2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.ArrayList; 2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.Collections; 2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.Comparator; 2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.Date; 2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.List; 2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/** 2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * AsciiHprofWriter produces hprof compatible text output for use with 3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * third party tools such as PerfAnal. 3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpublic final class AsciiHprofWriter { 3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final HprofData data; 3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final PrintWriter out; 3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Writes the provided data to the specified stream. 3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public static void write(HprofData data, OutputStream outputStream) throws IOException { 4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn new AsciiHprofWriter(data, outputStream).write(); 4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private AsciiHprofWriter(HprofData data, OutputStream outputStream) { 4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn this.data = data; 4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn this.out = new PrintWriter(outputStream); 4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private void write() throws IOException { 5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (HprofData.ThreadEvent e : data.getThreadHistory()) { 5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn out.println(e); 52 } 53 54 List<HprofData.Sample> samples 55 = new ArrayList<HprofData.Sample>(data.getSamples()); 56 Collections.sort(samples, SAMPLE_COMPARATOR); 57 int total = 0; 58 for (HprofData.Sample sample : samples) { 59 HprofData.StackTrace stackTrace = sample.stackTrace; 60 int count = sample.count; 61 total += count; 62 out.printf("TRACE %d: (thread=%d)\n", 63 stackTrace.stackTraceId, 64 stackTrace.threadId); 65 for (StackTraceElement e : stackTrace.stackFrames) { 66 out.printf("\t%s\n", e); 67 } 68 } 69 Date now = new Date(data.getStartMillis()); 70 // "CPU SAMPLES BEGIN (total = 826) Wed Jul 21 12:03:46 2010" 71 out.printf("CPU SAMPLES BEGIN (total = %d) %ta %tb %td %tT %tY\n", 72 total, now, now, now, now, now); 73 out.printf("rank self accum count trace method\n"); 74 int rank = 0; 75 double accum = 0; 76 for (HprofData.Sample sample : samples) { 77 rank++; 78 HprofData.StackTrace stackTrace = sample.stackTrace; 79 int count = sample.count; 80 double self = (double)count/(double)total; 81 accum += self; 82 83 // " 1 65.62% 65.62% 542 300302 java.lang.Long.parseLong" 84 out.printf("% 4d% 6.2f%%% 6.2f%% % 7d % 5d %s.%s\n", 85 rank, self*100, accum*100, count, stackTrace.stackTraceId, 86 stackTrace.stackFrames[0].getClassName(), 87 stackTrace.stackFrames[0].getMethodName()); 88 } 89 out.printf("CPU SAMPLES END\n"); 90 out.flush(); 91 } 92 93 private static final Comparator<HprofData.Sample> SAMPLE_COMPARATOR 94 = new Comparator<HprofData.Sample>() { 95 public int compare(HprofData.Sample s1, HprofData.Sample s2) { 96 return s2.count - s1.count; 97 } 98 }; 99} 100