1 /*
2  * Copyright (C) 2009 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 import java.io.File;
18 import java.lang.ref.WeakReference;
19 import java.lang.reflect.Method;
20 import java.lang.reflect.InvocationTargetException;
21 
22 public class Main {
23     private static final int TEST_LENGTH = 100;
24 
makeArray(int i)25     private static boolean makeArray(int i) {
26         return i % 10 == 0;
27     }
28 
fillArray(Object global[], Object local[], int i)29     private static void fillArray(Object global[], Object local[], int i) {
30         // Very stupid linking.
31         local[0] = global;
32         for (int j = 1; j < local.length; j++) {
33             local[j] = global[j];
34         }
35     }
36 
main(String[] args)37     public static void main(String[] args) {
38         // Create some data.
39         Object data[] = new Object[TEST_LENGTH];
40         for (int i = 0; i < data.length; i++) {
41             if (makeArray(i)) {
42                 data[i] = new Object[TEST_LENGTH];
43             } else {
44                 data[i] = String.valueOf(i);
45             }
46         }
47         for (int i = 0; i < data.length; i++) {
48             if (makeArray(i)) {
49                 Object data2[] = (Object[]) data[i];
50                 fillArray(data, data2, i);
51             }
52         }
53         System.out.println("Generated data.");
54 
55         File dumpFile = null;
56         File convFile = null;
57 
58         try {
59             // Now dump the heap.
60             dumpFile = createDump();
61 
62             // Run hprof-conv on it.
63             convFile = getConvFile();
64 
65             File hprof_conv = getHprofConf();
66             try {
67                 ProcessBuilder pb = new ProcessBuilder(
68                         hprof_conv.getAbsoluteFile().toString(),
69                         dumpFile.getAbsoluteFile().toString(),
70                         convFile.getAbsoluteFile().toString());
71                 pb.redirectErrorStream(true);
72                 Process process = pb.start();
73                 int ret = process.waitFor();
74                 if (ret != 0) {
75                     throw new RuntimeException("Exited abnormally with " + ret);
76                 }
77             } catch (Exception exc) {
78                 throw new RuntimeException(exc);
79             }
80         } finally {
81             // Delete the files.
82             if (dumpFile != null) {
83                 dumpFile.delete();
84             }
85             if (convFile != null) {
86                 convFile.delete();
87             }
88         }
89     }
90 
getHprofConf()91     private static File getHprofConf() {
92         // Use the java.library.path. It points to the lib directory.
93         File libDir = new File(System.getProperty("java.library.path"));
94         return new File(new File(libDir.getParentFile(), "bin"), "hprof-conv");
95     }
96 
createDump()97     private static File createDump() {
98         java.lang.reflect.Method dumpHprofDataMethod = getDumpHprofDataMethod();
99         if (dumpHprofDataMethod != null) {
100             File f = getDumpFile();
101             try {
102                 dumpHprofDataMethod.invoke(null, f.getAbsoluteFile().toString());
103                 return f;
104             } catch (Exception exc) {
105                 exc.printStackTrace(System.out);
106             }
107         } else {
108             System.out.println("Could not find dump method!");
109         }
110         return null;
111     }
112 
113     /**
114      * Finds VMDebug.dumpHprofData() through reflection.  In the reference
115      * implementation this will not be available.
116      *
117      * @return the reflection object, or null if the method can't be found
118      */
getDumpHprofDataMethod()119     private static Method getDumpHprofDataMethod() {
120         ClassLoader myLoader = Main.class.getClassLoader();
121         Class vmdClass;
122         try {
123             vmdClass = myLoader.loadClass("dalvik.system.VMDebug");
124         } catch (ClassNotFoundException cnfe) {
125             return null;
126         }
127 
128         Method meth;
129         try {
130             meth = vmdClass.getMethod("dumpHprofData",
131                     new Class[] { String.class });
132         } catch (NoSuchMethodException nsme) {
133             System.err.println("Found VMDebug but not dumpHprofData method");
134             return null;
135         }
136 
137         return meth;
138     }
139 
getDumpFile()140     private static File getDumpFile() {
141         try {
142             return File.createTempFile("test-130-hprof", "dump");
143         } catch (Exception exc) {
144             return null;
145         }
146     }
147 
getConvFile()148     private static File getConvFile() {
149         try {
150             return File.createTempFile("test-130-hprof", "conv");
151         } catch (Exception exc) {
152             return null;
153         }
154     }
155 }
156