Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 2cdbcc6ecbbbaaace7bb9813b2e1644c7730d22e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd" >
<!--
    Copyright (c) 2008, 2017 SAP AG and others.
    All rights reserved. This program and the accompanying materials
    are made available under the terms of the Eclipse Public License v1.0
    which accompanies this distribution, and is available at
    http://www.eclipse.org/legal/epl-v10.html
   
    Contributors:
        SAP AG - initial API and implementation
        IBM Corporation - minor updates
 -->
<task id="task_basictutorial" xml:lang="en-us">
	<title>Basic Tutorial</title>
	<prolog>
		<copyright>
			<copyryear year=""></copyryear>
			<copyrholder>
				Copyright (c) 2008, 2017 SAP AG and others.
			    All rights reserved. This program and the accompanying materials
			    are made available under the terms of the Eclipse Public License v1.0
			    which accompanies this distribution, and is available at
			    http://www.eclipse.org/legal/epl-v10.html
			</copyrholder>
		</copyright>
	</prolog>
	
	<taskbody>
		<context>
			<p>
				This tutorial provides a "jumping-off place" to get familiar with
				Memory Analyzer.
			</p>
			
			<p>
				If you are using Memory Analyzer installed into Eclipse rather than a stand-alone Memory Analyzer, 
				first open the 'Memory Analysis' perspective using:
				<menucascade>
 					<uicontrol>Window</uicontrol>
 					<uicontrol>Perspective</uicontrol>
 					<uicontrol>Open Perspective</uicontrol>
 					<uicontrol>Other ...</uicontrol>
 					<uicontrol>Memory Analysis</uicontrol>
				</menucascade>
			</p>

			<p>
				<b>Step 1 - Getting a Heap Dump</b>
			</p>

			<p>
				The Memory Analyzer works with
				<xref href="../concepts/heapdump.dita">heap dumps</xref>
				. Such a heap dump contains information about all Java objects alive
				at a given point in time. All current Java Virtual Machines can
				write heap dumps, but the exact steps depend on vendor, version and
				operation system. Find out more in the section
				<xref href="../tasks/acquiringheapdump.dita" />
				.
			</p>

			<p>
				Open
				<image href="../mimes/me76fc4.png">
					<alt></alt>
				</image>
				<xref format="html"
					href='javascript:liveAction(%22org.eclipse.mat.ui%22,%22org.eclipse.mat.ui.snapshot.actions.OpenSampleHeapDumpAction%22,%22org.eclipse.mat.ui.help/heapdump/HeapDumpSample.hprof%22)'>
					a sample heap dump</xref>
				if you view this page inside the Eclipse help center.
			</p>

			<p>
				For the purpose of this tutorial, we use Java 6 and JConsole on
				Windows. Start your application with Java 6, then start
				<codeph>&lt;jre6&gt;/bin/jconsole.exe</codeph>
				and select the running application (in this case Eclipse):
			</p>

			<image href="basictutorial_jconsole_open.png">
				<alt>JConsole dialog to open a connection to a Virtual Machine.</alt>
			</image>

			<p>
				Then, select the operation
				<i>dumpHeap</i>
				from the
				<i>com.sun.management.HotSpotDiagnostic</i>
				MBean. The first parameter
				<i>p0</i>
				is the full path to the heap dump file. Make sure you give it the
				file extension .hprof. The second parameter
				<i>p1</i>
				should be left at true as we are only interested in live objects.
			</p>

			<image href="basictutorial_jconsole_mbean.png">
				<alt>Select the dumpHeap method of the HotspotDiagnostics mbean.</alt>
			</image>

			<p>
				<b>Step 2 - The Overview</b>
			</p>

			<p>
				Open the heap dump via
				<menucascade>
					<uicontrol>File</uicontrol>
					<uicontrol>
						<image href="../mimes/i-openhd.png">
							<alt></alt>
						</image>
						Open Heap Dump...
					</uicontrol>
				</menucascade>
				to see the overview page.
			</p>

			<image href="basictutorial_overview.png">
				<alt>Memory Analyzer's overview page for a heap dump</alt>
			</image>

			<p>
				On the right, you'll find the size of the dump and the number of
				classes, objects and class loaders.
			</p>
			<p>
				If the total size of the dump is much smaller than the size of the file it is possible
				that the heap dump contained many 'garbage' objects which would be discarded at the next garbage
				collection. See the <xref href="../reference/inspections/unreachable_objects.dita">unreachable objects</xref>
				query to examine these 'garbage' objects.
			</p>
			<p>
				Right below, the pie chart gives an impression on the biggest
				objects in the dump. Move your mouse over a slice to see the details
				of the objects in the object inspector on the left. Click on any
				slice to drill down and follow for example the outgoing references. 
			</p>

			<p>
				<b>Step 3 - The Histogram</b>
			</p>

			<p>
				Select the
				<i>histogram</i>
				from the tool bar to list the number of instances per class, the
				<xref href="../concepts/shallowretainedheap.dita">shallow size</xref>
				and the
				<xref href="../concepts/shallowretainedheap.dita">retained size</xref>
				.
			</p>

			<image href="basictutorial_histogram.png">
				<alt>Histogram</alt>
			</image>

			<p>
				The Memory Analyzer displays by default the retained size of
				individual objects. However, the retained size of a set of objects -
				in this case all instances of a particular class - needs to be
				calculated. 
			</p>

			<p>
				To approximate the retained sizes for all rows, pick
				<image href="../mimes/i-calcrs.png">
					<alt>Calculate retained size</alt>
				</image> icon
				from the tool bar. Alternatively, select a couple rows and use the
				context menu.
			</p>

			<image href="basictutorial_calc_retained.png">
				<alt>Select calculate retained sizes from the tool bar</alt>
			</image>

			<p>
				Using the
				<b>context menu</b>
				, you can drill-down into the set of objects
				which the selected row
				represents. For example, you can list the
				objects with outgoing or
				incoming references. Or group the objects
				by the value of an
				attribute. Or group the collections by their
				size. Or or or...
			</p>

			<p>
				One thing that makes the Memory Analyzer so powerful is the fact
				that one can run any action on any set of objects. Just drill down
				and slice your objects the way you need them.
			</p>

			<image href="basictutorial_context_menu.png">
				<alt>Drill down via the context menu</alt>
			</image>

			<p>
				Another important feature is the facility to
				<b>group any histogram by class loader, packages or superclass</b>
				.
			</p>

			<image href="basictutorial_group_by.png">
				<alt>Group the histogram by class loader or package via the tool bar</alt>
			</image>

			<p>
				Any decent application loads different components by different
				class loaders. The Memory Analyzer attaches a meaningful label to
				the class loader - in the case of OSGi bundles it is the bundle id.
				Therefore it becomes a lot easier to divide the heap dump into
				smaller parts.
			</p>
			
			<p>
				More: <xref href="../tasks/analyzingclassloader.dita"/>
			</p>

			<image href="basictutorail_by_classloader.png">
				<alt>Histogram grouped by class loader</alt>
			</image>

			<p>
				Grouping the histogram by packages allows to drill-down along the
				Java package hierarchy.
			</p>

			<image href="basictutorail_by_package.png">
				<alt>Histogram grouped by packages</alt>
			</image>
			
			<p>
				Grouping the histogram by superclass provides an easy way to find for example all the subclasses of java.util.AbstractMap, etc...
			</p>
			
			<image href="basictutorial_by_superclass.png">
				<alt>Histogram grouped by superclass</alt>
			</image>

			<p>
				<b>Step 4 - The Dominator Tree</b>
			</p>

			<p>
				The
				<xref href="../concepts/dominatortree.dita">dominator tree</xref>
				displays the biggest objects in the heap dump. The next level of the
				tree lists those objects that would be garbage collected if all
				incoming references to the parent node were removed.
			</p>

			<p>
				The dominator tree is a powerful tool to investigate which objects
				keep which other objects alive. Again, the tree can be grouped by
				class loader (e.g. components) and packages to ease the analysis.
			</p>

			<image href="basictutorial_dominator_tree.png">
				<alt>Dominator Tree</alt>
			</image>

			<p>
				<b>Step 5 - Path to GC Roots</b>
			</p>

			<p>
				<xref href="../concepts/gcroots.dita">Garbage Collections Roots (GC roots)</xref>
				are objects that are kept alive by the Virtual Machines itself.
				These include for example the thread objects of the threads
				currently running, objects currently on the call stack and classes
				loaded by the system class loader.
			</p>

			<p>
				The (reverse) reference chain from an object to a GC root - the so
				called path to GC roots - explains why the object cannot be garbage
				collected. The path helps solving the classical memory leak in Java:
				those leaks exist because an object is still referenced even though
				the program logic will not access the object anymore.
			</p>

			<image href="basictutorial_path_menu.png">
				<alt>Select path to GC roots from the context menu</alt>
			</image>

			<p>
				Initially, the GC root reached by the shortest path is selected.
			</p>

			<image href="basictutorial_path.png">
				<alt>Path to GC roots</alt>
			</image>

			<p>
				<b>Step 6 - The Leak Report</b>
			</p>

			<p>
				The Memory Analyzer can inspect the heap dump for leak suspects,
				e.g. objects or set of objects which are suspiciously big. 
			</p>

			<image href="basictutorial_run_leak_suspects.png">
				<alt>Run the leak report</alt>
			</image>

			<p>
				Learn more in this blog posting:
				<xref format="html"
					href="http://memoryanalyzer.blogspot.com/2008/05/automated-heap-dump-analysis-finding.html">Automated Heap Dump Analysis: Finding Memory Leaks with One
					Click</xref>
				.
			</p>
		</context>
	</taskbody>
	<related-links>
		<link href="../concepts/dominatortree.dita" />
		<link href="../concepts/gcroots.dita" />
	</related-links>
</task>

Back to the top