| <?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><stack frame></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> |