1 /* 2 * Copyright (C) 2010 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 dalvik.system.profiler; 18 19 import java.io.IOException; 20 import java.io.OutputStream; 21 import java.io.PrintWriter; 22 import java.util.ArrayList; 23 import java.util.Collections; 24 import java.util.Comparator; 25 import java.util.Date; 26 import java.util.List; 27 28 /** 29 * AsciiHprofWriter produces hprof compatible text output for use with 30 * third party tools such as PerfAnal. 31 */ 32 public final class AsciiHprofWriter { 33 34 private final HprofData data; 35 private final PrintWriter out; 36 37 /** 38 * Writes the provided data to the specified stream. 39 */ write(HprofData data, OutputStream outputStream)40 public static void write(HprofData data, OutputStream outputStream) throws IOException { 41 new AsciiHprofWriter(data, outputStream).write(); 42 } 43 AsciiHprofWriter(HprofData data, OutputStream outputStream)44 private AsciiHprofWriter(HprofData data, OutputStream outputStream) { 45 this.data = data; 46 this.out = new PrintWriter(outputStream); 47 } 48 write()49 private void write() throws IOException { 50 for (HprofData.ThreadEvent e : data.getThreadHistory()) { 51 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