`

JHAT

 
阅读更多

 

http://jovial.com/hat/doc/README.html

 

HAT -- The Java Heap Analysis Tool

Bill Foote
bill.foote at sun d o t com, billf at jovial d o t com

Introduction

This document describes a heap dump file for Java programs, and a tool to analyze these files. This tool can help you to debug an analyze the objects in a running Java program. It is particularly useful when debugging unintentional object retention.

Unintentional object retention, a phenomenon sometimes called "memory leaks," can come about in several ways. I call it a unintentional object retention when an object that is no longer needed is referenced through some path from the rootset. This can happen, for example, if an unintentional static reference to an object remains after the object is no longer needed, if an Observer or Listener fails to de-register itself from its subject when it is no longer needed, or if a Thread that refers to an object does not terminate when it should.

This tool helps to debug unnecessary object retention by providing a convenient means to browse the object topology in a heap snapshot that is generated by the Java VM. This shapshot is in a JDK 1.2 heap profile file (generated with -Xrunhprof). The tool allows a number of queries, including "show me all reference paths from the rootset to this object". It is this query that is most useful for finding unnecessary object retention.

This document will discuss each of the queries that the analysis tool offers.

Donations to Charities

HAT was done mostly nights and weekends, starting when I was at JavaSoft. To cover Sun there is a license, but as the author may I make a small request? Could you please read the words I've written on the charitable donations page, and do as you feel appropriate? Thank you.

Generating a .hprof File and Running the Program

To generate a .hprof file, you should run java with the -Xrunhprof flag. The format recognized by this program first appeared in JDK 1.2 beta3. HAT must be given a binary hprof file. This is done with the "format=b" modifier to the -Xrunhprof command. For example, to run the program Main and generate a binary heap profile in the file dump.hprof, use the following command:

    java -Xrunhprof:file=dump.hprof,format=b Main

As of JDK 1.2, you can add a heap dump to a .hprof file with control-backslash under Unix or OS/X, or control-break in Win32. Some sample .hprof files are provided in the hprof_files subdirectory (doc/hprof_files). They were produced with a small slot car animation program I wrote in a former life. The source for that program can be found under http://jovial.com/slotCar/.

To run the hat server program, use the run shell script or batch file provided in the bin directory. You'll probably want to copy it and hat.jar somewhere sensible (I use ~/bin on Unix and OS/X, and c:/bin on Windows). Once that's done, to analyze a slot car hprof file, you can do the following:

	cd doc/hprof_files
	hat -port=7002 slot_car_jdk_1_5_0_beta2.hprof


If a port is not specified, it defaults to 7000.

The server can compare two heap dumps, and it's possible to specify a numbered heap dump in the file. For example, to compare the first and second heap dump in slotCar.hprof, use this command:

	hat -baseline slot_car_from_jdk_1_2_beta3.hprof#1 slot_car_from_jdk_1_2_beta3.hprof#2

You can specify a file that influences the reachable objects query. This file lists the data members that should be excluded when generating this query. This can be used to determined the size of a given object and all objects reachable from it, excluding observers and other objects that aren't "owned" by the target object. To specify a set of data members to exclude, use the -exclude command line option:

	./hat -exclude slotCar.exclude slot_car_from_jdk_1_2_beta3.hprof

This file should contain the fully-qualified name of each data member to exclude, with a newline between each data member. If this file is modified while a server is running, it will be re-read.

The program sets itself up as an http server on the port you specify. You access it by bringing up the default page in the browser of your choice. For example, if you're running hat on the same computer as your browser, you can probably call it "localhost", if not "127.0.0.1" will do. Assuming your OS supports calling it localhost, you could access the server started above by navigating to the URL "http://localhost:7002/". From there, you can run other queries by clicking on hyperlinks, or by directly typing in URLs.

This document contains links to sample HTML pages generated by the server. The links within these sample pages will not work. To generate a working example, run the server program with the provided .hprof file.

Note on JDK versions

The feature of generating a .hprof file was considered experimental in JDK 1.2 through 1.4. It worked well with the classic VM on JDK 1.2, but some VMs and some versions of the JDK might not produce .hprof files compatible with HAT. As of JDK 1.5, .hprof files are produced by an experimental agent that connects to the VM via a supported profiling interface. As such, it's more stable and dependable, though I'm told there were some issues with version prior to update 3. I recommend using a JDK version of 1.5 update 3 or better with HAT.

Sample HAT queries

The All Classes Query

Example: http://localhost:7002/ 
Example: http://localhost:7002/allClassesWithPlatform/

The default page shows you all of classes present on the heap, excluding platform classes. This list is sorted by fully-qualified class name, and broken out by package. By clicking on the name of a class, you are taken to the Class query. At the bottom of the page is a link you can click to be taken to other queries.

The second variant of this query includes the platform classes. Platform classes include classes whose fully-qualified names start with things like "java.", "sun.", "javax.swing.", or "char[". The list of prefixes is in a system resource file called "resources/platform_names.txt". If you want to override this list, just replace it in the jar file, or arrange for your replacement to occur first on the classpath when hat is invoked.

The Class Query

Example: http://localhost:7002/class/jovial.slotCar.Car

The Class query shows you information about a class. This includes its superclass, any subclasses, instance data members, and static data members. From this page you can navigate to any of the classes that are referenced, or you can navigate to an Instances query.

The Instances Query

Example: http://localhost:7002/instances/jovial.slotCar.Car
Example: http://localhost:7002/allInstances/jovial.slotCar.animator.Drawable

The instances query shows you all instances of a given class. The "allInstances" variant includes instances of subclasses of the given class as well. From here, you can navigate back to the source class, or you can navigate to an Object query on one of the instances.

The Object Query

Example: http://localhost:7002/object/ee3077c8

The object query gives you information about an object that was on the heap. From here, you can navigate to the class of the object, to the value of any data members of the object. You can also navigate to objects that refer to this object. Perhaps the most valuable query is at the end: The Roots query ("Reference Chains from Rootset").

Note that the object query also gives you a stack backtrace of the point of allocation of the object.

The Roots Query

Example: http://localhost:7002/roots/ee3077c8
Example: http://localhost:7002/allRoots/ee3077c8

The roots query gives you reference chains from the rootset to a given object. It will give you one chain for each member of the rootset from which the given object is reachable. When calculating these chains, it does a depth-first search, so that it will provide reference chains of minimal length.

There are two kinds of roots query: One that excludes weak references ("roots"), and one that includes them ("allRoots"). A weak reference is a reference object that does not prevent its referent from being made finalizable, finalized, and then reclaimed. Weak references are subclasses of sun.misc.Ref, or java.lang.ref.WeakReference as of JDK 1.2. If an object is only referred to by a weak reference, it usually isn't considered to be retained, because the garbage collector can collect it as soon as it needs the space.

The server sorts rootset reference chains by the type of the root, in this order:

  • Static data members of Java classes.
  • Java local variables. For these roots, the thread responsible for them is shown. Because a Thread is a Java object, this link is clickable. This allows you, for example, to easily navigate to the name of the thread.
  • Native static values.
  • Native local variables. Again, such roots are identified with their thread.

This is probably the most valuable query in HAT, if you're debugging unintentional object retention. Once you find an object that's being detained, this query tells you why it's being retained.

The Reachable Objects Query

Example: http://localhost:7002/reachableFrom/ee3077c8

This query, accessible from the Object query, shows the transitive closure of all objects reachable from a given object. This list is sorted in decreasing size, and alphabetically within each size. At the end, the total size of all of the reachable objects is given. This can be useful for determining the total runtime footprint of an object in memory, at least in systems with simple object topologies.

This query is most valuable when used in conjunction with the "-exclude" command line option, described above. This is useful, for example, if the object being analyzed is an Observable. By default, all of its Observers would be reachable, which would count against the total size. -exclude allows you to exclude the data members java.util.Observable.obs and java.util.Observable.arr.

The Instance Counts for All Classes Query

Example: http://localhost:7002/showInstanceCounts/ 
Example: http://localhost:7002/showInstanceCounts/includePlatform/

This query shows the count of instances for every class in the system, excluding platform classes. It is sorted in descending order, by instance count. A good way to spot a problem with unintentional object retention is to run a program for a long time with a variety of input, then request a heap dump. Looking at the instance counts for all classes, often a class you know will jump out at you, because there are more than you expect. Then, you can analyze them to determine why they're being retained (possibly using the roots query).

There's also a variant of this that includes platform classes. See the notes under the All Classes query for notes about what is considered to be a platform class.

The All Roots Query

Example: http://localhost:7002/showRoots/

This query shows all members of the rootset.

The New Instances Query

Example: http://localhost:7002/newInstances/java.awt.Point
Example: http://localhost:7002/allNewInstances/java.lang.Object

The New Instances query is only available if you invoke the hat server with two heap dumps. It is like the Instances query, but it only shows "new" instances. An instance is considered new if it is in the second heap dump, and there is no object of the same type with the same ID in the baseline heap dump. An object's ID is a 32 bit integer that uniquely identifies the object, and it is assigned by the VM. In the VM implementations that were current when HAT was written (JDK 1.1.x and betas of JDK 1.2), an object's ID was the address of its handle, so it was pretty stable. Because handle address could be re-used, the new instances query could give inaccurate results. In more modern VM implementations, the object ID could well be less table, and the results might be unusable. With betas of JDK 1.2, comparing snapshots taken within a relatively short interval, the results were pretty good. YMMV.

Summary

The hat server can be valuable for debugging and understanding programs. It allows you to navigate object structures to learn how objects are interconnected in a program. It also allows you to trace the references to a given object from the rootset, which can be valuable for tracking down unnecessary object retention. We found the hat server to be a valuable debugging aid, and hope that you will, too.

For more information, please consult the HAT page at http://hat.dev.java.net/.

MAIN PAGE |  SENDING COMMENTS |  DONATIONS |  HISTORY

分享到:
评论

相关推荐

    jhat 使用方法 -----------

    jhat 使用方法指南 jhat 是 JavaHeapAnalysisTool 的缩写,它是一个 Java 虚拟机(JVM)堆分析工具,由 Sun Microsystems 提供,用于对 Java 应用程序的堆内存进行分析和诊断。下面是 jhat 的使用方法指南: jhat ...

    JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解.docx

    JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解 本文将对一些常用的 JVM 性能调优监控工具进行介绍,包括 jps、jstack、jmap、jhat、jstat 等工具的使用详解。这些工具对于 Java 程序员来说是必备的,...

    lanlan2017#JavaReadingNotes#4.2.5 jhat:虚拟机堆转储快照分析工具1

    - 第4章 虚拟机性能监控、故障处理工具- 4.2 基础故障处理工具JDK提供jhat(JVM Heap Analysis Tool)命令与jmap搭配使用,来

    JVM 性能调优监控工具 jps、jstack、jmap、jhat、jstat、hprof 使用详解.zip

    计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习...

    JVM调优前戏之JDK命令行工具.docx

    需要注意的是,在服务器上不建议直接运行jhat,因为jhat是一个耗时并且耗费硬件资源的过程。 nên普通将服务器生成的dump文件复制到本地或其他机器上进行分析。 jhat的命令格式为: ``` jhat [dumpfile] ``` 例如:...

    Java Magazine JulyAugust 2017.pdf

    jhat是一个用于分析Java堆转储的工具,但它由于许多新的分析工具的出现变得不再那么必要。 此外,杂志内容还包括: - **编辑部评论** 杂志编辑部评论了协同工作的挑战,并解释了如JDK 9这样的主要版本发布经常...

    jdk8 解压缩安装包下载地址https://www.oracle.com/java/technologies/download

    **Java Development Kit (JDK) 8 是Oracle提供的用于开发和运行Java应用程序的重要工具包。在本篇中,我们将深入探讨JDK8的下载、安装以及解决Linux环境下可能遇到的问题。** 首先,JDK8是Java编程语言的核心组成...

    虚拟机监控工具详请.rar

    虽然jhat功能强大,但由于现代内存分析工具有更多高级功能,jhat在某些情况下可能已被替代。 6. **jstack(Stack Trace for Java)**: jstack用于打印Java线程的堆栈跟踪信息,这对于诊断线程阻塞和死锁问题非常...

    基于Spring Boot框架的JVM性能调优与内存管理.zip

    提供多种JVM监控工具的使用示例,如jps、jstat、jmap、jhat、jstack、jinfo和jcmd,帮助开发者实时监控JVM的运行状态。 3. 内存管理与垃圾收集 演示如何通过调整JVM参数(如XX:PretenureSizeThreshold)来影响...

    JVM命令行监测工具详解

    jhat是JDK自带的堆分析工具,用于分析由jmap导出的内存映像文件。但jhat已不再推荐使用,因为它在处理大型堆文件时可能效率低下。现在更推荐使用如JProfiler、VisualVM等图形化工具进行分析。 总结: 这些命令行...

    jvm工具、参数调优&调试技巧.doc

    4. **jhat(Java Heap Analysis Tool)**:当JVM生成堆转储文件后,jhat可以用来分析内存使用情况,查找内存泄漏和对象引用问题。 5. **jmap(Memory Map for Java)**:它可以导出堆内存快照,供其他工具如jhat或...

    Java监控工具.pdf

    3. **jhat**: jhat 用于分析Java堆转储。当需要在内存分析工具中进一步分析堆内存时,这个工具非常有用。 4. **jmap**: jmap 可以提供堆内存和JVM内存使用情况的详细信息,例如堆dump。使用`jmap -heap process_id`...

    Java虚拟机调优及问题排查手册.docx

    使用jhat命令可以查看当前的堆栈快照详细信息: ``` jhat -J-Xmx1024m ``` Tomcat调优 Tomcat调优是指通过各种配置和参数来优化Tomcat的性能。常用的配置包括关闭数据库连接、JVM调优、Tomcat线程池连接数修改等...

    推荐普通开发者学习使用的6个JDK内建工具Java开发Ja

    JMap用于生成堆转储文件,而JHAT(Java Heap Analysis Tool)则用于分析这些转储文件,查找内存泄漏等问题。这两个工具配合使用,可以帮助开发者找出导致内存占用过高的原因,从而优化内存管理。 6. **JFR (Java ...

    Windows下如何手工抓取was的dump文件

    IBM提供了一个名为 `jhat` 的工具(位于Java SDK的 `bin` 目录下),它是一个命令行工具,用于分析heap dump。运行 `jhat` 并指定dump文件路径,然后在浏览器中查看分析结果。 ```cmd jhat ``` 此外,还有一些第...

    visualvm_211.zip

    例如,JConsole 主要用于监控JMX服务,而JMap 和 JHat 分别用于生成堆转储和分析堆内存,这些转储文件可以在VisualVM 中进一步分析。 总的来说,VisualVM 是Java开发者和系统管理员的强大武器,它能够帮助我们理解...

    Java诊断工具源代码.zip

    1. **JVM内置工具**:Java虚拟机(JVM)提供了多种内置的诊断工具,如`jps`(Java进程状态工具)、`jstat`(Java统计监视工具)、`jinfo`(配置信息工具)、`jmap`(映射工具)、`jhat`(堆分析工具)和`jstack`...

    Java开发常用指令大全.zip

    `jhat`与`jmap`配合使用,可以分析堆转储文件,查找内存泄漏或不合理的对象引用。 9. **jstack**:线程堆栈跟踪 `jstack`用于打印Java进程的线程堆栈信息,有助于定位死锁或线程阻塞的问题。 10. **jinfo**:...

    HotSpot实战高清版本

    本书深入浅出地讲解了 ...数的分发机制、VTABLE 和 ITABLE、异常表、虚拟机监控工具(如 jinfo、jstack、jhat、jmap 等)的实现原 理和开发方法、Attach 机制、基于 GUI 的 JVM 分析工具(如 MAT、VisualVM)等内容。

Global site tag (gtag.js) - Google Analytics