blob: e619f2577c7b40aa6e53d96eb76dbcb7cbbef389 [file] [log] [blame]
Andy McFaddenaa336022009-04-27 13:19:51 -07001<html>
2<head>
3 <title>Dalvik Heap Profiling</title>
4</head>
5
6<body>
7<h1>Dalvik Heap Profiling</h1>
8
9<p>
10The Dalvik virtual machine can produce a complete dump of the contents
11of the virtual heap. This is very useful for debugging memory usage
12and looking for memory leaks. Getting at the information can be tricky,
13but has become easier in recent releases.
14
15
16<h2>Getting the data</h2>
17<p>
18The first step is to cause the VM to dump its status, and then pull the hprof
19data off. The exact manner for doing so has changed over time.
20</p><p>
21There is a <code>runhat</code> shell function, added by
22<code>build/envsetup.sh</code>, that partially automates these steps. The
23function changes in each release to accommodate newer behavior, so you have
24to be careful that you don't use the wrong version.
25</p><p>
26
27<h3>Early releases (1.0/1.1)</h3>
28<p>
29You can only generate heap data on the emulator or a device with root
30access, because of the way the dump is initiated and where the output
31files go.
32</p><p>
33Get a command shell on the device:
34<blockquote><pre>
35$ adb shell
36</pre></blockquote>
37</p><p>
38You can verify that you're running as root with the <code>id</code> command.
39The response should look like <code>uid=0(root) gid=0(root)</code>. If not,
40type <code>su</code> and try again. If <code>su</code> fails, you're out
41of luck.
42
43</p><p>
44Next, ensure the target directory exists:
45<blockquote><pre>
46# mkdir /data/misc
47# chmod 777 /data/misc
48</pre></blockquote>
49
50</p><p>
51Use <code>ps</code> or DDMS to determine the process ID of your application,
52then send a <code>SIGUSR1</code> to the target process:
53
54<blockquote><pre>
55# kill -10 &lt;pid&gt;
56</pre></blockquote>
57
58</p><p>
59The signal causes a GC, followed by the heap dump (to be completely
60accurate, they actually happen concurrently, but the results in the heap
61dump reflect the post-GC state). This can take a couple of seconds,
62so you have to watch for the GC log message to know when it's complete.
63</p><p>
64Next:
65
66<blockquote><pre>
67# ls /data/misc/heap-dump*
68# exit
69</pre></blockquote>
70
71</p><p>
72Use <code>ls</code> to check the file names, then <code>exit</code> to quit
73the device command shell.
74
75</p><p>
76You should see two output files, named
77<code>/data/misc/heap-dump-BLAH-BLAH.hprof</code> and
78<code>.hprof-head</code>, where BLAH is a runtime-generated value
79that ensures the filename is unique. Pull them off of the device and
80remove the device-side copy:
81
82<blockquote><pre>
83$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof tail.hprof
84$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof-head head.hprof
85$ adb shell rm /data/misc/heap-dump-BLAH-BLAH.hprof /data/misc/heap-dump-BLAH-BLAH.hprof-head
86</pre></blockquote>
87
88</p><p>
89Merge them together and remove the intermediates:
90
91<blockquote><pre>
92$ cat head.hprof tail.hprof &gt; dump.hprof
93$ rm head.hprof tail.hprof
94</pre></blockquote>
95
96</p><p>
97You now have the hprof dump in <code>dump.hprof</code>.
98
99</p><p>
100
101
102<h3>"Cupcake" release (1.5)</h3>
103<p>
104Some steps were taken to make this simpler. Notably, the two output
105files are now combined for you, and a new API call was added that allows
106a program to write the dump at will to a specific file. If you're not
107using the API call, you still need to be on an emulator or running as root.
108(For some builds, you can use <code>adb root</code> to restart the adb
109daemon as root.)
110</p><p>
111The basic procedure is the same as for 1.0/1.1, but only one file will
112appear in <code>/data/misc</code> (no <code>-head</code>), and upon
113completion you will see a log message that says "hprof: heap dump completed".
114It looks like this in the log:
115
116<blockquote><pre>
117I/dalvikvm( 289): threadid=7: reacting to signal 10
118I/dalvikvm( 289): SIGUSR1 forcing GC and HPROF dump
119I/dalvikvm( 289): hprof: dumping VM heap to "/data/misc/heap-dump-tm1240861355-pid289.hprof-hptemp".
120I/dalvikvm( 289): hprof: dumping heap strings to "/data/misc/heap-dump-tm1240861355-pid289.hprof".
121I/dalvikvm( 289): hprof: heap dump completed, temp file removed
122</pre></blockquote>
123
124</p><p>
125Summary: as above, use <code>mkdir</code> and <code>chmod</code>
126to ensure the directory exists and is writable by your application.
127Send the <code>SIGUSR1</code> or use the API call to initiate a dump.
128Use <code>adb pull &lt;dump-file&gt;</code> and <code>adb shell rm
129&lt;dump-file&gt;</code> to retrieve the file and remove it from the
130device. The concatenation step is not needed.
131
132</p><p>
133The new API is in the <code>android.os.Debug</code> class:
134<blockquote><pre>
135public static void dumpHprofData(String fileName) throws IOException
136</pre></blockquote>
137When called, the VM will go through the same series of steps (GC and
138generate a .hprof file), but the output will be written to a file of
139your choice, e.g. <code>/sdcard/myapp.hprof</code>. Because you're
140initiating the action from within the app, and can write the file to
141removable storage or the app's private data area, you can do this on a
142device without root access.
143
144
145<h2>Examining the data</h2>
146<p>
147The data file format was augmented slightly from the common hprof format,
148and due to licensing restrictions the modified <code>hat</code> tool cannot
149be distributed. A conversion tool, <code>hprof-conv</code>, can be used
150to strip the Android-specific portions from the output. This tool was
151first included in 1.5, but will work with older versions of Android.
152</p><p>
153The converted output should work with any hprof data analyzer, including
154<code>jhat</code>, which is available for free in the Sun JDK, and
155Eclipse MAT.
156
157<!-- say something about how to track down common problems, interesting
158 things to look for, ...? -->
159
160</body>
161</html>