java.lang.OutOfMemoryError (OOM)解密 & Java heap dumps 解析 (二)

What Is a Java Heap Dump?

We've learned that a Java heap is a runtime data area where all class instances and arrays are allocated and shared among all Java Virtual Machine threads during execution of the JVM. A Java heap dump is a snapshot of a Java heap at a specific time. It's like taking a picture of a busy warehouse at a given time. If we look at the picture, we can identify what items were available at that time. Some items may be shipped to Canada a few minutes later, but you can see them in the picture because they were there at the time of the snapshot.

Because the Java specification does not mention the Java heap dump, there are different forms of Java heap dump implementations from different Java Virtual Machines. The IBM Java heap dump provides information mostly about the Java heap.

The Sun Microsystems hprof Java heap dump provides information about the Java Virtual Machine stacks, the runtime constant pool as well as the Java heap.

什麼是Java堆轉儲?

我們已經瞭解到Java堆是所有的Java類實例以及數組分配的地方,它是一個運行時數據存放區域,在JVM執行期間,Java堆在所有的JVM線程之間共享。Java堆轉儲是Java堆在一個特定時刻的快照,就像是在某一時刻對一個繁忙的倉庫拍個快照。如果我們查看這張照片,我們可以看出哪些商品在那一時刻可用。一些商品可能幾分鐘後就會被裝運到加拿大,但是你可以在這張照片中看到他們,因爲在拍照的那一刻,它們就在那兒。

由於Java規範中並沒有提到Java堆轉儲,有來自不同的Java虛擬機不同形式的Java堆轉儲的實現。 IBMJava堆轉儲提供的主要是關於Java堆的信息。

Sun MicrosystemsHPROF Java堆轉儲提供了Java虛擬機棧信息,運行時常量池以及Java堆信息。

How Can I Generate Java Heap Dumps?
A Java heap dump is usually automatically generated by the Java Virtual Machine, but you can also force Java heap dump generation. On most IBM Java Virtual Machines, Java heap dumps are generated automatically when the Java heap becomes exhausted. On most Sun Microsystems JVMs, you need to configure the virtual machine to generate Java heap dumps. If you want to generate a Java heap dump when a java.lang.OutOfMemoryError occurs, you need to set the -XX:+HeapDumpOnOutOfMemoryError command-line option on certain releases of Sun's JVM. You could also use a HPROF profiler by using the -agentlib:hprof=heap=dump command-line option. You could also use jmap if your Sun JVM provides the utility. For example, jmap -dump 1234 will generate the Java heap dump from the process whose identifier is 1234. You could utilize JConsole by calling the HotSpotDiagnostic MBean and the dumpHeap operation if it's available from your Sun JVM.

If you want to generate Java heap dumps for Java virtual machine crashes (an unexpected termination of process) or user signals on IBM JVMs, you can set the environment variableIBM_HEAPDUMP or IBM_HEAP_DUMP to TRUE. For example, you can send the IBM Java virtual machine the signal SIGQUIT for the Linux operating systems and AIX operating systems or SIGINT(Control-Break key combination) for Windows to generate Java heap dumps. The IBM JVM provides an API, com.ibm.jvm.Dump.HeapDump(), that you can invoke from application code to generate Java heap dumps programmatically.

Please refer to the documentation of your JVM for detailed information since these options vary by platform and implementation.

如何生成Java Heap Dumps?

Java堆轉儲通常由由Java虛擬機自動生成,但是,你也可以強制生成Java堆轉儲。對於大多數IBM Java虛擬機,當Java堆被耗盡時,會自動生成Java堆轉儲。對於大多數Sun公司的JVM,您需要手工配置虛擬機參數來生成Java堆轉儲。如果您想在報java.lang.OutOfMemoryError時生成Java堆轉儲,您需要在Sun的JVM的某些特定版本上設置-XX:+HeapDumpOnOutOfMemoryError命令行選項。你也可以使用一個HPROF分析器,通過設置它的-agentlib:hprof=heap=dump命令行選項來生成。當然你也可以使用Jmap如果你的Sun的JVM提供了這個實用工具。例如,你可以通過jmap –dump 1234在爲進程Id爲1234的Java虛擬機進程來生成Java堆轉儲,其標識符爲1234。如果你使用的Sun公司的Java虛擬機有提供JConsole工具,也可以通過調用它的HotSpotDiagnostic MBean和dumpHeap命令來生成。

如果你想在Java虛擬機崩潰(意外終止進程)時生成Java堆轉儲,或者user signals on IBM JVMs(此句不知如何翻譯爲好,求各位大神詳解),你可以將IBM_HEAPDUMP或IBM_HEAP_DUMP環境變量設置爲true。 例如,你可以在Linux或AIX系統上面通過發送SIGQUIT信號給Java虛擬機來產生Java堆轉儲,在Windows系統上面可以通過發送SIGINT信號給Java虛擬機來產生Java堆轉儲(如果是在cmd命令行啓動,可以通過Ctrl+C組合鍵)。當然你也可以通過調用IBM提供的com.ibm.jvm.Dump.HeapDump()API方法以編程方式在生產Java堆轉儲。

Where Can I Find Java Heap Dumps?
You can find Java heap dumps in the current working directory of the Java Virtual Machine process, unless you specify a different location. You can specify the location with the environment variable IBM_HEAPDUMPDIRor_CEE_DMPTARGon IBM JVMs. If there's not enough space available for Java heap dumps or the JVM cannot acquire write-permission in the location, Java heap dumps are generated to the operating system's temporary directory on the IBM JVM. Please refer to your operating system manual for the location of the system's temporary directory and its configuration.

哪裏可以找到Java堆轉儲文件?

你可以在Java虛擬機進程的當前工作目錄下面找到Java堆轉儲文件,除非你指定了一個不同的位置。如果你使用的是IBM的JVM,你也可以使用IBM_HEAPDUMPDIR或者_CEE_DMPTARG環境變量來指定Java堆轉儲生成的位置。如果沒有足夠的空間可用於Java堆轉儲或JVM無法獲得的堆轉儲位置的寫權限,Java堆轉儲將會生成在IBM JVM所在操作系統的臨時目錄下請參考你的操作系統手冊去查看系統的臨時目錄位置以及它的配置。

What Do Java Heap Dumps Look Like and How Can I read Them?
Nowadays, the majority of Java heap dump formats are generated in binary. Thus you might want to use a tool unless your brain can interpret hexadecimal codes without any headaches.

The IBM HeapAnalyzer is one of the most popular Java heap analysis tools. It can analyze all Java heap dump formats provided by Sun, HP and most of the Java heap dump formats provided by IBM. It's powered by object query engines and patent-pending heuristic analysis engines. I've been developing the IBM HeapAnalyzer from scratch since 2003, spending my vacation, weekends and weeknights on it. The IBM HeapAnalyzer was so successful that IBM decided to make the IBM HeapAnalyzer an official IBM software product and bundle it with existing products. So I donated all the source code of IBM HeapAnalyzer to IBM to run it on an Eclipse-based interface. Now the IBM HeapAnalyzer has a daughter, MDD4J, which always reminds me of my late daughter lost while I was working on the MDD4J project. The IBM HeapAnalyzer has been the top technology at IBM alphaWorks for six consecutive years since its inception as of March 2009.

Whether your Java heap dump is in binary or text/ascii format, the heap dump contains information about all the live objects that are on the Java heap such as address, object size, and referenced addresses. Let's take a look at the text/ascii format Java heap dumps since binary heap dumps have similar information but are in hexadecimal format to save disk space.

那麼Java堆轉儲到底是什麼樣子呢?我們又如何讀懂Java堆轉儲信息呢? 

        如今,大多數Java堆轉儲格式都是以二進制格式生成。所以,你也許會想使用一個工具去分析這些堆轉儲信息,除非你的大腦可以理解的十六進制代碼,確不會感覺到頭疼。

IBMHeapAnalyzer軟件是最流行的Java堆分析工具之一。它可以分析所有由SunHP提供的Java堆轉儲格式,以及大部分IBM提供的Java堆轉儲格式。HeapAnalyzer是由對象查詢引擎和正在申請專利的啓發式分析引擎所驅動來提供分析功能。自2003年的第一個原型版以來,我一直在從事IBM HeapAnalyzer的持續開發,花費了我大部分假期、週末甚至週末的晚上。由於IBM HeapAnalyzer如此的成功,所以,IBM公司決定讓IBMHeapAnalyzer列爲正式的IBM軟件產品,並且綁定到現在有的產品中。所以,我貢獻了所有的IBM HeapAnalyzer源代碼,以便其可以運行在基於Eclipse的界面上運行。現在,IBMHeapAnalyzer有了一個子產品MDD4J,它總是讓我回想起我當時正在研究MDD4J項目期間失去的女兒。自20093月成立以來IBMHeapAnalyzer已經連續六年被認爲是IBM alphaWorks最頂尖的技術。

無論你的Java堆轉儲是二進制格式還是ASCII文本格式,堆轉儲裏面都包含了所有活動對象的內存地址、對象大小、引用地址等信息。

 上一篇:java.lang.OutOfMemoryError (OOM)解密 & Java heap dumps 解析 (一)

原文鏈接地址:http://java.sys-con.com/node/1229281


發佈了31 篇原創文章 · 獲贊 24 · 訪問量 84萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章