| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package dalvik.system.profiler; |
| |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.PrintWriter; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.Date; |
| import java.util.List; |
| |
| /** |
| * AsciiHprofWriter produces hprof compatible text output for use with |
| * third party tools such as PerfAnal. |
| */ |
| public final class AsciiHprofWriter { |
| |
| private final HprofData data; |
| private final PrintWriter out; |
| |
| /** |
| * Writes the provided data to the specified stream. |
| */ |
| public static void write(HprofData data, OutputStream outputStream) throws IOException { |
| new AsciiHprofWriter(data, outputStream).write(); |
| } |
| |
| private AsciiHprofWriter(HprofData data, OutputStream outputStream) { |
| this.data = data; |
| this.out = new PrintWriter(outputStream); |
| } |
| |
| private void write() throws IOException { |
| for (HprofData.ThreadEvent e : data.getThreadHistory()) { |
| out.println(e); |
| } |
| |
| List<HprofData.Sample> samples |
| = new ArrayList<HprofData.Sample>(data.getSamples()); |
| Collections.sort(samples, SAMPLE_COMPARATOR); |
| int total = 0; |
| for (HprofData.Sample sample : samples) { |
| HprofData.StackTrace stackTrace = sample.stackTrace; |
| int count = sample.count; |
| total += count; |
| out.printf("TRACE %d: (thread=%d)\n", |
| stackTrace.stackTraceId, |
| stackTrace.threadId); |
| for (StackTraceElement e : stackTrace.stackFrames) { |
| out.printf("\t%s\n", e); |
| } |
| } |
| Date now = new Date(data.getStartMillis()); |
| // "CPU SAMPLES BEGIN (total = 826) Wed Jul 21 12:03:46 2010" |
| out.printf("CPU SAMPLES BEGIN (total = %d) %ta %tb %td %tT %tY\n", |
| total, now, now, now, now, now); |
| out.printf("rank self accum count trace method\n"); |
| int rank = 0; |
| double accum = 0; |
| for (HprofData.Sample sample : samples) { |
| rank++; |
| HprofData.StackTrace stackTrace = sample.stackTrace; |
| int count = sample.count; |
| double self = (double)count/(double)total; |
| accum += self; |
| |
| // " 1 65.62% 65.62% 542 300302 java.lang.Long.parseLong" |
| out.printf("% 4d% 6.2f%%% 6.2f%% % 7d % 5d %s.%s\n", |
| rank, self*100, accum*100, count, stackTrace.stackTraceId, |
| stackTrace.stackFrames[0].getClassName(), |
| stackTrace.stackFrames[0].getMethodName()); |
| } |
| out.printf("CPU SAMPLES END\n"); |
| out.flush(); |
| } |
| |
| private static final Comparator<HprofData.Sample> SAMPLE_COMPARATOR |
| = new Comparator<HprofData.Sample>() { |
| public int compare(HprofData.Sample s1, HprofData.Sample s2) { |
| return s2.count - s1.count; |
| } |
| }; |
| } |