blob: a9d72b5584ca4c18fa76db33b8ee8b0c36f5ce38 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2008, 2021 SAP AG.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
SAP AG - initial API and implementation
IBM Corporation
-->
<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd" >
<task id="task_analyzingthreads" xml:lang="en-us">
<title>Analyzing Threads</title>
<prolog>
<copyright>
<copyryear year=""></copyryear>
<copyrholder>
Copyright (c) 2008, 2021 SAP AG, IBM Corporation and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-2.0/
</copyrholder>
</copyright>
</prolog>
<taskbody>
<context>
<p>
Memory Analyzer provides several queries to inspect the threads at the
moment the snapshot was taken.
</p>
<p><b>Threads Overview</b></p>
<p>
To get an overview of all the threads in the heap dump, use the "Thread Overview" button
in the toolbar, as shown on the image below. Alternatively one could use the
<menucascade>
<uicontrol>Query Browser</uicontrol>
<uicontrol>Thread Overview and Stacks</uicontrol>
</menucascade>
query:
</p>
<image href="../mimes/threads_overview.png">
<alt>screen shot of thread overview</alt>
</image>
<p>
The query provide some properties like thread name, thread object, Context Classloader, and more
for each of the threads.
</p>
<p>
Some heap dump formats (e.g. HPROF dumps from recent Java 6 VMs and IBM system dumps)
contain information about the call stacks of threads, and the Java local objects per
stack frame. The <uicontrol>Max. Locals' Retained Heap</uicontrol> column shows the maximum retained
heap of each stack frame's locals which helps quickly explore why a thread is retaining
a lot of heap. When a stack frame is the first selected item the <wintitle>Inspector</wintitle> view shows the class of the
method of the frame.
The context menu for a stack frame operates on the locals in that frame,
and so calculating the precise or approximate retained size when stack frames are selected
shows how much memory each stack frame is retaining, or equivalently how much memory would
be freed if all the locals of that frame were cleared.
<ol>
<li>Select all threads using <uicontrol>ctrl+A</uicontrol> or <uicontrol>command+A</uicontrol></li>
<li>Expand one level with <uicontrol>shift+numpad-plus</uicontrol></li>
<li>Select all threads and stack frames using <uicontrol>ctrl+A</uicontrol> or <uicontrol>command+A</uicontrol></li>
<li>Calculate retained size using one of the toolbar items
<uicontrol>Calculate Minimum Retained Size (quick approx.)</uicontrol>
or <uicontrol>Calculate Precise Retained Size</uicontrol></li>
<li>Find the far right hand column <uicontrol>Retained Size</uicontrol></li>
<li>Move it to somewhere more convenient by
dragging the column header or by clicking on the filter cell,
then using <uicontrol>shift+up-arrow</uicontrol></li>
<li>Sort on the column</li>
<li>Examine the stack frames retaining the most memory</li>
</ol>
</p>
<p>
Exploring the call-stacks and the local Java objects is a powerful feature, giving a
debugger like capabilities over a snapshot. It allows analyzing in detail the reasons
for memory intensive operations. It also allow using Memory Analyzer
not only for memory-related problems, but also for a wide range of other problems
such as unresponsive applications.
</p>
<p><b>Threads Details</b></p>
<p>
You can proceed with the analysis of a single thread by using the
<menucascade>
<uicontrol>Java Basics</uicontrol>
<uicontrol>Thread Details</uicontrol>
</menucascade>
context menu. Memory Analyzer provides an extension point such that extensions can
provide semantic information about the thread's activity. The result of the Thread Details
query will contain such information (if available), some overview information, and
possibly the stacktrace of the thread.
</p>
<p>
For DTFJ based dumps (IBM system dumps and IBM PHD files with associated java dump) the thread
details view gives more information, including the thread state, priority and native stack trace.
</p>
<p>
<image href="../mimes/thread_details.png">
<alt>Thread details from a DTFJ dump showing DTFJ Name, JNIEnv, Priority, State and Native id.</alt>
</image>
</p>
<p><b>Threads Stacks in Dumps from IBM VMs and HPROF Dumps</b></p>
<p>The DTFJ parser and HPROF parser provide more control over viewing thread stacks. This is configured using the
DTFJ Parser or HPROF Parser preferences page. The options are as follows:
<dl>
<dlentry>
<dt>Normal</dt>
<dd>Stack frames are only shown in the thread stacks view.</dd>
</dlentry>
<dlentry>
<dt>Only stack frames as pseudo-objects</dt>
<dd>Stack frames are shown in all views such as paths to GC roots, outbound references from threads, as pseudo-objects.
Local variables references in the stack frames are shown as outbound references from the frame.
This makes it easy to find which stack frames keep objects alive. For DTFJ, the size of the stack frame is the
size on the Java stack, not the heap. HPROF stack frames have zero size.</dd>
</dlentry>
<dlentry>
<dt>Stack frames as pseudo-objects and running methods as pseudo-classes</dt>
<dd>Stack frames are shown in all views such as paths to GC roots, outbound references from threads, as pseudo-objects.
Local variables references in the stack frames are shown as outbound references from the frame.
This makes it easy to find which stack frames keep objects alive.
The stack frames are given a pseudo-type depending based on the method which is running in the frame.
By viewing the number of instances of that pseudo-type it is easy to see which methods are running across
all the threads and which methods use a lot of stack. This can help solve StackOverflowErrors.</dd>
</dlentry>
<dlentry>
<dt>Stack frames as pseudo-objects and all methods as pseudo-classes</dt>
<dd>Only available with the DTFJ Parser. Stack frames are shown in all views such as paths to GC roots, outbound references from threads, as pseudo-objects.
Local variables references in the stack frames are shown as outbound references from the frame.
This makes it easy to find which stack frames keep objects alive.
The stack frames are given a pseudo-type depending based on the method which is running in the frame.
By viewing the number of instances of that pseudo-type it is easy to see which methods are running across
all the threads and which methods use a lot of stack. This can help solve StackOverflowErrors.
All other methods are also created as pseudo-class objects. The size of the method pseudo-class object is
the size of the byte code and JITted code, which in other modes is accumulated into the size of the
defining class. This makes it easy to find methods which consume a lot of non-heap memory for byte code
and JITted code.</dd>
</dlentry>
</dl>
</p>
<p><b>Normal operation with stack frames not considered as objects.</b></p>
<p>
<image href="../mimes/thread_frames0.png">
<alt>outbound references from thread without stack frames as objects</alt>
</image>
</p>
<p><b>Stack frames as pseudo-objects.</b></p>
<p>Note that the type of the stack frame is <codeph>&lt;stack frame&gt;</codeph>.</p>
<p>
<image href="../mimes/thread_frames1.png">
<alt>outbound references from thread with stack frames as objects</alt>
</image>
</p>
<p><b>Stack frames as pseudo-objects and running methods as pseudo-classes.</b></p>
<p>Note the different types for the stack frame such as <codeph>java.io.FileStream.getBytes([BIII)I;</codeph>.</p>
<p>
<image href="../mimes/thread_frames2.png">
<alt>outbound references from thread with stack frames as objects and methods as classes</alt>
</image>
</p>
<p>The class histogram shows that only running methods are pseudo-classes, and the size of the class object is 0.</p>
<p>
<image href="../mimes/thread_classes2.png">
<alt>class histogram showing running methods as pseudo-classes</alt>
</image>
</p>
<p><b>Stack frames as pseudo-objects and all methods as pseudo-classes.</b></p>
<p>The outbound references tree looks the same,
but the class histogram has a lot more pseudo-classes with 0 instances (i.e. with no running methods), and the
pseudo-class objects have a non-zero size.
<image href="../mimes/thread_classes3.png">
<alt>class histogram showing all methods as pseudo-classes</alt>
</image>
</p>
</context>
</taskbody>
</task>