xref: /aosp_15_r20/dalvik/docs/heap-profiling.html (revision 055d459012065f78d96b68be8421640240ddf631)
1*055d4590SKeyi Gui<html>
2*055d4590SKeyi Gui<head>
3*055d4590SKeyi Gui    <title>Dalvik Heap Profiling</title>
4*055d4590SKeyi Gui</head>
5*055d4590SKeyi Gui
6*055d4590SKeyi Gui<body>
7*055d4590SKeyi Gui<h1>Dalvik Heap Profiling</h1>
8*055d4590SKeyi Gui
9*055d4590SKeyi Gui<p>
10*055d4590SKeyi GuiThe Dalvik virtual machine can produce a complete dump of the contents
11*055d4590SKeyi Guiof the virtual heap.  This is very useful for debugging memory usage
12*055d4590SKeyi Guiand looking for memory leaks.  Getting at the information can be tricky,
13*055d4590SKeyi Guibut has become easier in recent releases.
14*055d4590SKeyi Gui</p><p>
15*055d4590SKeyi GuiIn what follows, the version number refers to the software release
16*055d4590SKeyi Guirunning on the phone.  To take advantage of the DDMS integration, you will
17*055d4590SKeyi Guialso need a sufficiently recent version of DDMS.
18*055d4590SKeyi Gui
19*055d4590SKeyi Gui
20*055d4590SKeyi Gui<h2>Getting the data</h2>
21*055d4590SKeyi Gui<p>
22*055d4590SKeyi GuiThe first step is to cause the VM to dump its status, and then pull the hprof
23*055d4590SKeyi Guidata off.  The exact manner for doing so has changed over time.
24*055d4590SKeyi Gui</p><p>
25*055d4590SKeyi GuiThere is a <code>runhat</code> shell function, added by
26*055d4590SKeyi Gui<code>build/envsetup.sh</code>, that partially automates these steps.  The
27*055d4590SKeyi Guifunction changes in each release to accommodate newer behavior, so you have
28*055d4590SKeyi Guito be careful that you don't use the wrong version.
29*055d4590SKeyi Gui</p><p>
30*055d4590SKeyi Gui
31*055d4590SKeyi Gui<h3>Early releases (1.0/1.1)</h3>
32*055d4590SKeyi Gui<p>
33*055d4590SKeyi GuiYou can only generate heap data on the emulator or a device with root
34*055d4590SKeyi Guiaccess, because of the way the dump is initiated and where the output
35*055d4590SKeyi Guifiles go.
36*055d4590SKeyi Gui</p><p>
37*055d4590SKeyi GuiGet a command shell on the device:
38*055d4590SKeyi Gui<blockquote><pre>
39*055d4590SKeyi Gui$ adb shell
40*055d4590SKeyi Gui</pre></blockquote>
41*055d4590SKeyi Gui</p><p>
42*055d4590SKeyi GuiYou can verify that you're running as root with the <code>id</code> command.
43*055d4590SKeyi GuiThe response should look like <code>uid=0(root) gid=0(root)</code>.  If not,
44*055d4590SKeyi Guitype <code>su</code> and try again.  If <code>su</code> fails, you're out
45*055d4590SKeyi Guiof luck.
46*055d4590SKeyi Gui
47*055d4590SKeyi Gui</p><p>
48*055d4590SKeyi GuiNext, ensure the target directory exists:
49*055d4590SKeyi Gui<blockquote><pre>
50*055d4590SKeyi Gui# mkdir /data/misc
51*055d4590SKeyi Gui# chmod 777 /data/misc
52*055d4590SKeyi Gui</pre></blockquote>
53*055d4590SKeyi Gui
54*055d4590SKeyi Gui</p><p>
55*055d4590SKeyi GuiUse <code>ps</code> or DDMS to determine the process ID of your application,
56*055d4590SKeyi Guithen send a <code>SIGUSR1</code> to the target process:
57*055d4590SKeyi Gui
58*055d4590SKeyi Gui<blockquote><pre>
59*055d4590SKeyi Gui# kill -10 &lt;pid&gt;
60*055d4590SKeyi Gui</pre></blockquote>
61*055d4590SKeyi Gui
62*055d4590SKeyi Gui</p><p>
63*055d4590SKeyi GuiThe signal causes a GC, followed by the heap dump (to be completely
64*055d4590SKeyi Guiaccurate, they actually happen concurrently, but the results in the heap
65*055d4590SKeyi Guidump reflect the post-GC state).  This can take a couple of seconds,
66*055d4590SKeyi Guiso you have to watch for the GC log message to know when it's complete.
67*055d4590SKeyi Gui</p><p>
68*055d4590SKeyi GuiNext:
69*055d4590SKeyi Gui
70*055d4590SKeyi Gui<blockquote><pre>
71*055d4590SKeyi Gui# ls /data/misc/heap-dump*
72*055d4590SKeyi Gui# exit
73*055d4590SKeyi Gui</pre></blockquote>
74*055d4590SKeyi Gui
75*055d4590SKeyi Gui</p><p>
76*055d4590SKeyi GuiUse <code>ls</code> to check the file names, then <code>exit</code> to quit
77*055d4590SKeyi Guithe device command shell.
78*055d4590SKeyi Gui
79*055d4590SKeyi Gui</p><p>
80*055d4590SKeyi GuiYou should see two output files, named
81*055d4590SKeyi Gui<code>/data/misc/heap-dump-BLAH-BLAH.hprof</code> and
82*055d4590SKeyi Gui<code>.hprof-head</code>, where BLAH is a runtime-generated value
83*055d4590SKeyi Guithat ensures the filename is unique.  Pull them off of the device and
84*055d4590SKeyi Guiremove the device-side copy:
85*055d4590SKeyi Gui
86*055d4590SKeyi Gui<blockquote><pre>
87*055d4590SKeyi Gui$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof tail.hprof
88*055d4590SKeyi Gui$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof-head head.hprof
89*055d4590SKeyi Gui$ adb shell rm /data/misc/heap-dump-BLAH-BLAH.hprof /data/misc/heap-dump-BLAH-BLAH.hprof-head
90*055d4590SKeyi Gui</pre></blockquote>
91*055d4590SKeyi Gui
92*055d4590SKeyi Gui</p><p>
93*055d4590SKeyi GuiMerge them together and remove the intermediates:
94*055d4590SKeyi Gui
95*055d4590SKeyi Gui<blockquote><pre>
96*055d4590SKeyi Gui$ cat head.hprof tail.hprof &gt; dump.hprof
97*055d4590SKeyi Gui$ rm head.hprof tail.hprof
98*055d4590SKeyi Gui</pre></blockquote>
99*055d4590SKeyi Gui
100*055d4590SKeyi Gui</p><p>
101*055d4590SKeyi GuiYou now have the hprof dump in <code>dump.hprof</code>.
102*055d4590SKeyi Gui</p><p>
103*055d4590SKeyi Gui
104*055d4590SKeyi Gui
105*055d4590SKeyi Gui<h3>Android 1.5 ("Cupcake")</h3>
106*055d4590SKeyi Gui<p>
107*055d4590SKeyi GuiSome steps were taken to make this simpler.  Notably, the two output
108*055d4590SKeyi Guifiles are now combined for you, and a new API call was added that allows
109*055d4590SKeyi Guia program to write the dump at will to a specific file.  If you're not
110*055d4590SKeyi Guiusing the API call, you still need to be on an emulator or running as root.
111*055d4590SKeyi Gui(For some builds, you can use <code>adb root</code> to restart the adb
112*055d4590SKeyi Guidaemon as root.)
113*055d4590SKeyi Gui</p><p>
114*055d4590SKeyi GuiThe basic procedure is the same as for 1.0/1.1, but only one file will
115*055d4590SKeyi Guiappear in <code>/data/misc</code> (no <code>-head</code>), and upon
116*055d4590SKeyi Guicompletion you will see a log message that says "hprof: heap dump completed".
117*055d4590SKeyi GuiIt looks like this in the log:
118*055d4590SKeyi Gui
119*055d4590SKeyi Gui<blockquote><pre>
120*055d4590SKeyi GuiI/dalvikvm(  289): threadid=7: reacting to signal 10
121*055d4590SKeyi GuiI/dalvikvm(  289): SIGUSR1 forcing GC and HPROF dump
122*055d4590SKeyi GuiI/dalvikvm(  289): hprof: dumping VM heap to "/data/misc/heap-dump-tm1240861355-pid289.hprof-hptemp".
123*055d4590SKeyi GuiI/dalvikvm(  289): hprof: dumping heap strings to "/data/misc/heap-dump-tm1240861355-pid289.hprof".
124*055d4590SKeyi GuiI/dalvikvm(  289): hprof: heap dump completed, temp file removed
125*055d4590SKeyi Gui</pre></blockquote>
126*055d4590SKeyi Gui
127*055d4590SKeyi Gui</p><p>
128*055d4590SKeyi GuiSummary: as above, use <code>mkdir</code> and <code>chmod</code>
129*055d4590SKeyi Guito ensure the directory exists and is writable by your application.
130*055d4590SKeyi GuiSend the <code>SIGUSR1</code> or use the API call to initiate a dump.
131*055d4590SKeyi GuiUse <code>adb pull &lt;dump-file&gt;</code> and <code>adb shell rm
132*055d4590SKeyi Gui&lt;dump-file&gt;</code> to retrieve the file and remove it from the
133*055d4590SKeyi Guidevice.  The concatenation step is not needed.
134*055d4590SKeyi Gui
135*055d4590SKeyi Gui</p><p>
136*055d4590SKeyi GuiThe new API is in the <code>android.os.Debug</code> class:
137*055d4590SKeyi Gui<blockquote><pre>
138*055d4590SKeyi Guipublic static void dumpHprofData(String fileName) throws IOException
139*055d4590SKeyi Gui</pre></blockquote>
140*055d4590SKeyi GuiWhen called, the VM will go through the same series of steps (GC and
141*055d4590SKeyi Guigenerate a .hprof file), but the output will be written to a file of
142*055d4590SKeyi Guiyour choice, e.g. <code>/sdcard/myapp.hprof</code>.  Because you're
143*055d4590SKeyi Guiinitiating the action from within the app, and can write the file to
144*055d4590SKeyi Guiremovable storage or the app's private data area, you can do this on a
145*055d4590SKeyi Guidevice without root access.
146*055d4590SKeyi Gui
147*055d4590SKeyi Gui
148*055d4590SKeyi Gui<h3>Android 1.6 ("Donut")</h3>
149*055d4590SKeyi Gui<p>
150*055d4590SKeyi GuiNo real change to the way profiling works.
151*055d4590SKeyi GuiHowever, 1.6 introduced the <code>WRITE_EXTERNAL_STORAGE</code>
152*055d4590SKeyi Guipermission, which is required to write data to the SD card.  If you're
153*055d4590SKeyi Guiaccustomed to writing profile data to <code>/sdcard</code>, you will
154*055d4590SKeyi Guineed to enable the permission in your application's manifest.
155*055d4590SKeyi Gui</p>
156*055d4590SKeyi Gui
157*055d4590SKeyi Gui
158*055d4590SKeyi Gui<h3>Android 2.0 ("Eclair")</h3>
159*055d4590SKeyi Gui<p>
160*055d4590SKeyi GuiIn 2.0, features were added that allow DDMS to request a heap dump on
161*055d4590SKeyi Guidemand, and automatically pull the result across.  Select your application
162*055d4590SKeyi Guiand click the "dump HPROF file" button in the top left.  This always
163*055d4590SKeyi Guiwrites files to the SD card, so
164*055d4590SKeyi Guiyou must have a card inserted and the permission enabled in your application.
165*055d4590SKeyi Gui</p>
166*055d4590SKeyi Gui
167*055d4590SKeyi Gui
168*055d4590SKeyi Gui<h3>Android 2.2 ("Froyo")</h3>
169*055d4590SKeyi Gui<p>
170*055d4590SKeyi GuiDDMS heap dump requests are now streamed directly out of the VM, removing
171*055d4590SKeyi Guithe external storage requirement.
172*055d4590SKeyi Gui</p>
173*055d4590SKeyi Gui
174*055d4590SKeyi Gui<h3>Android 2.3 ("Gingerbread")</h3>
175*055d4590SKeyi Gui<p>
176*055d4590SKeyi GuiThe <code>kill -10</code> (<code>SIGUSR1</code>) method of generating heap
177*055d4590SKeyi Guidumps has been removed from the VM.
178*055d4590SKeyi Gui</p>
179*055d4590SKeyi Gui
180*055d4590SKeyi Gui<h3>Android 3.0 ("Honeycomb")</h3>
181*055d4590SKeyi Gui<p>
182*055d4590SKeyi GuiA new command-line tool has been added:
183*055d4590SKeyi Gui</p>
184*055d4590SKeyi Gui<blockquote><pre>am dumpheap &lt;pid&gt; &lt;output-file-name&gt;</pre></blockquote>
185*055d4590SKeyi Gui<p>
186*055d4590SKeyi GuiUnlike the <code>SIGUSR1</code> approach, this does not require a rooted
187*055d4590SKeyi Guiphone.  It's only necessary for the application to be debuggable (by setting
188*055d4590SKeyi Gui<code>android:debuggable="true"</code> in the <code>&lt;application&gt;</code>
189*055d4590SKeyi Guielement of the app manifest).  The output file is opened by "am", which
190*055d4590SKeyi Guimeans you can write the data to a file on <code>/sdcard</code> without
191*055d4590SKeyi Guineeding the <code>WRITE_EXTERNAL_STORAGE</code> permission in your app.
192*055d4590SKeyi Gui<p>
193*055d4590SKeyi GuiThe <code>runhat</code> shell function has been updated to use this.
194*055d4590SKeyi Gui</p>
195*055d4590SKeyi Gui
196*055d4590SKeyi Gui<h2>Examining the data</h2>
197*055d4590SKeyi Gui<p>
198*055d4590SKeyi GuiThe data file format was augmented slightly from the common hprof format,
199*055d4590SKeyi Guiand due to licensing restrictions the modified <code>hat</code> tool cannot
200*055d4590SKeyi Guibe distributed.  A conversion tool, <code>hprof-conv</code>, can be used
201*055d4590SKeyi Guito strip the Android-specific portions from the output.  This tool was
202*055d4590SKeyi Guifirst included in 1.5, but will work with older versions of Android.
203*055d4590SKeyi Gui</p><p>
204*055d4590SKeyi GuiThe converted output should work with any hprof data analyzer, including
205*055d4590SKeyi Gui<code>jhat</code>, which is available for free in the Sun JDK, and
206*055d4590SKeyi GuiEclipse MAT.
207*055d4590SKeyi Gui
208*055d4590SKeyi Gui<!-- say something about how to track down common problems, interesting
209*055d4590SKeyi Gui     things to look for, ...? -->
210*055d4590SKeyi Gui
211*055d4590SKeyi Gui</p><p>
212*055d4590SKeyi Gui<address>Copyright &copy; 2009 The Android Open Source Project</address>
213*055d4590SKeyi Gui
214*055d4590SKeyi Gui</body>
215*055d4590SKeyi Gui</html>
216