處理此問題步驟
Java Out of Memory
1. 收集與分析verbose gc 的錯誤訊息輸出
??將“verbosegc“參數加入命令提示列啟動Server,這將會將GC 的活動資訊顯示在標準輸出/輸入,轉到stdout/stderr 的檔案中。執行應用程式直到問題再次產生。
??確定在java out of memory 之前,JVM 做如下內容:
??Full GC run:
執行full GC 與所有soft/weak/phantomly reachable 的物件能被移除與這些空間能被回收,在下面網址可以找到更多不同等級物件消耗細項說明:
http://java.sun.com/developer/technicalArticles/ALT/RefObj
你能檢查full GC 在out of memory 訊息之前做,接下來的一個訊息顯示當GC 已經完成(訊息的格式是依照JVM 定義,檢查JVM 的Help message 以了解訊息格式):
[memory ] 7.160: GC 131072K->130052K (131072K) in 1057.359 ms
下面是上面格式的說明(注意:相似格式將會被使用在遍及這份文件):
[memory ] <start>: GC <before>K-><after>K (<heap>K), <total> ms
[memory ] <start> - start time of collection (seconds since jvm start)
[memory ] <before> - memory used by objects before collection (KB)
[memory ] <after> - memory used by objects after collection (KB)
[memory ] <heap> - size of heap after collection (KB)
[memory ] <total> - total time of collection (milliseconds)
然而,這無法使用訊息推斷soft/weak/phantomly reachable objects 被移除。假如GC 演算法是generational 演算法,你會看到verbose 輸出像這樣:
[memory ] 2.414: Nursery GC 31000K->20760K (75776K), 0.469 ms
上述是nursery GC(或young GC)循環將會提升正在執行的objects 從
nursery(或young space)到old space。這個循環不是重要的分析,更詳細項目有關generational 演算法可以在JVM 的文件中找到;假如GC 的循環不是發生在java out of memory,這樣就可能是JVM 的bug。
??Full compaction:
保證JVM 做適當的緊密程度工作,記憶體沒有碎裂,能防止large objects被配置而且引發一個java out of memory 錯誤。Java Objects 需要連續的記憶區塊,假如沒有空的記憶體區塊,那麼JVM 將無法配置一個large objects,它將無法符合任何一個空的區塊。在這個情況下JVM 將會做full compaction,這樣才會有更多連續記憶體區塊能夠符合容納large objects。Compaction 工作包含移動objects(data)從java heap memory 一個區堆到另一個與更新references 到這些objects 的指定的新的位置上。JVM 將不會重排所有objects,除非這是需要的。這是減少GC 循環的暫停時間。我們能否透過verbose gc 訊息檢查出記憶體碎裂的java out of memory。
假如我們看到輸出像下列所示,即使仍有空的java heap 而out of memory 還是會發生,是因為記憶體碎裂的原因。
[memory ] 8.162: GC 73043K->72989K (131072K) in 12.938 ms
[memory ] 8.172: GC 72989K->72905K (131072K) in 12.000 ms
[memory ] 8.182: GC 72905K->72580K (131072K) in 13.509 ms
java.lang.OutOfMemoryError
以上的情況你能夠看出max heap 是被設定128MB 與JVM 丟出out ofmemory 當實體記憶體使用只有72580K,Heap 使用率只有55%。因此,即使當有45%free heap 的時候,在這個案例記憶體碎裂的影響仍會丟出out of
memory。這是JVM 的bug 或是限制。你必需聯絡原廠請求協助。
2. 假如JVM 運作是正常的
假如JVM 運作是正常的(的在上述所提及的動作),那麼java out of memory可能是應用程式的問題。這個應用程式可能不斷洩漏一些java memory,可能是會引發這個問題。或者是應用程式使用過多的objects 它需要更多的heapmemory,以下是可以在這個應用程式中做檢查的:
??應用程式的caching:
假如應用程式在記憶體中caches java objects,那麼我們將需要確定這個cache 是否一直在成長;可能需要在cache 中限制objects 的數量。我們能試著降低這個限制看看是否它會降低java heap 使用量。JAVA soft references 像softly reachable objects 一樣使用data caching,當JVM 執行發生out of heap 時,是允許被移除。
??執行過久的objects:
假如在應用系統裡有在Heap 中存在過久的objects,那麼我們可以儘可能地試著降低存在的objects。例如:調校HTTP session timeout 將能幫助更快回收無效session objects。
??Memory leaks:
一個memory leak 的範例是在應用系統中使用database connectionpools。當使用connection pools,JDBC statement 與resultset objects必需確定最後有被關閉。這基於事實,這由於從pool 中的connection
objects 使用呼叫close(),將簡單connection 傳回到pool 以提供重新使用,若沒有真正關閉connection 與關聯到的statement/resultset
objects。
??增加java heap:
我們也能試著增加java heap 假如可能的話看是否能解決問題。
3. 假如不是屬於前兩者的狀況:
那們我們需要使用JVMPI(JVM Profiler Interface)基礎profiler 像Jprobe 或OptimizeIt 去找出那些Objects 是佔住java heap,profilers 也從這些對象正被建立的地方,在java code 裡的細節地方上。這份資料不包括在每profiler 上的細節。profiler 文件可能提到有關如何設定與啟動應用系統與profilers。 通常,基於JVMPI
的profilers 會有過多負擔與大大降低應用系統的效能。因此,在上線環境裡使用這些profilers 是不適當的。
For Native OOM Problem:
1. 收集下列資訊
??–verbosegc output to monitor the java heap usage.
這將能幫助了解應用系統的java memory 需求。應用系統它可能會需要獨立使用的實際java heap,在JVM 啟動時預留最大的heap 設定(使用-Xmx 參數在java 命令提示列)與在其他用途是不允許預留記憶體。在這個Jrockit 的案例,使用-verbose 取代-verbosegc 如同在GC 資訊中增加給codegen 資訊。??記錄Process virtual memory size 從應用系統被啟動時,開始在JVM執行到out of native memory;這將能幫助了解不管是process 真的達到作業系統的大小限制。在Windows 的案例,遵照下列程度監控virtual process size:在開始\執行,輸入”perfmon”並且按OK在Performance 圖形上方按下“+“按鍵選擇下面項目:
效能物件: Process (不是預設的processor)
從清單選取計數器: Virtual Bytes
從清單選擇例項: Select the JVM (java) instance
按 “新增”, 並且 “關閉”
在Unix 或Linux 中對於PID 而言,virtual memory size 能夠使用這個命令看到:– ps –p <PID> -o vsz.
在Linux 中每一個java thread 都會有單一個JVM instance 以process方式顯示,假如我們選擇一個root java process 的PID,這個root javaprocess 可以使用ps 命令加上-forest 參數能夠被發現,例如:ps –IU
<user> --forst 將會顯示某一特定使用者所有process 的ASCII 的樹狀結構顯示,你還可以從這樹狀結構找到root java。
2. 機器上可用的記憶體
假如機器RAM 與swap space 是不足,那麼作業系統將無法提供更多的記憶體給process,那麼也可能造成out of memory 的結果,確定同機器上的RAM
與swap space 在硬碟空間的加總是足夠執行所有的Process。
3. Java heap 調校
假如java heap 的使用都在max heap 之內,那麼可以考慮降低max heap的大小,以提供更多的native memory 給JVM 使用。這並不是一個解決方案,但是一個測試的變通方法。因為作業系統限定process 大小,我們需要在javaheap 與native heap 之間達到一個平衡。
4. JVM 的Native memory 使用量
在所有的classes 被載入JVM 的Native memory 使用量是將可預期會趨於平穩,並且方法已被呼叫(code 的產生已經結束)。應用系統通常發生在最初的幾個小時,在那之後,JVM 可能在執行時載入class,code 的最佳化只需要很小的native memory。
為了減少問題,試著取消執行時最佳化並且檢查是否有何不同。??在這個jrockit 案例,參數-Xnoopt 能夠取消執行時最佳化。在SUN的JVM,參數-Xint 將強制JVM執行在interpreted mode(nocode generation)。假如執行時native memory 使用量仍持續成長,那麼問題就可能是在native
code 這邊發生。
5. 應用程式中Third party 的native modules 或JNI code
檢查不論你是使用Third party 的native module 像是database driver,這些native modules 可能也會配置native memory 並且漏洞可能就是這些modules。基於縮小問題,你能試著重建問題在不使用協助廠商的driver,例如:你能使用pure java drivers 取代native database drivers。檢查你的應用系統是否使用JNI 的程式碼,這也可能造成native memory洩漏,並且你也可以嘗試執行應用系統儘量不使用JNI 程式碼。
6. 假如照上述步驟仍無法找出native memory 問題
那麼你就得向JVM 廠商取得能偵測native memory 配置的特別的版本並且更多有關JVM 上有關記憶體洩漏的訊息。
結論
系統開發時往往問題發生out of memory,或記憶體一直成長無法透過GC回到平均值時,這往往不知道該如何處理此問題所在,到底是應用系統問題,還是JDK 發生的問題,以上的這些是針對有關Memory leak 問題進行說明的了解,與問題排解原則加以說明,期望日後再碰到此問題能有所參考依據與檢測的方式,以讓此類問題能夠不再發生。
分享到:
相关推荐
"Java.lang.OutOfMemoryError: Java heap space 解决方法" Java.lang.OutOfMemoryError: Java heap space 是 Java 中的一个常见错误,它发生时,Java 虚拟机 (JVM) 无法分配对象,因为堆空间不足。下面是解决该问题...
2. **Java Heap Space 异常产生的原因**: - **内存分配不足**:如果启动 Java 应用程序时没有为 JVM 设置足够的堆空间,随着应用运行,可能会出现内存不足的情况。 - **内存泄漏**:程序中存在未释放的对象引用,...
### 解决Java_heap_space问题:深入理解与策略 在Java应用程序开发与运行过程中,经常会遇到一个常见的内存管理问题——“Java heap space”。这个问题通常表现为Java虚拟机(JVM)在执行过程中因可用堆内存不足而...
### Java 错误处理:java.lang.OutOfMemoryError: Java heap space 在Java应用程序开发过程中,经常遇到的一个问题就是内存溢出错误,特别是在处理大量数据或长时间运行的应用时。其中,“java.lang....
### 编译时出现java.lang.OutOfMemoryError Java heap space异常 #### 一、问题概述 在进行Java项目编译的过程中,可能会遇到`java.lang.OutOfMemoryError: Java heap space`这种异常。这类异常通常表明Java虚拟机...
在Java编程中,"java heap space"内存溢出是一个常见的问题,它通常发生在应用程序尝试分配超过JVM堆内存限制的对象时。这个问题对于任何Java开发者来说都至关重要,因为如果不妥善处理,可能会导致程序崩溃。以下是...
### Myeclipse下java.lang.OutOfMemoryError: Java heap space的解决方案 在使用Myeclipse进行Java开发时,可能会遇到`java.lang.OutOfMemoryError: Java heap space`这个错误提示。这种异常通常发生在应用程序占用...
Java程序在运行过程中可能会遇到各种异常,其中"nested exception is java.lang.OutOfMemoryError: Java heap space"是一个常见的问题,通常发生在程序试图分配超过堆内存限制的空间时。这个错误表明Java虚拟机(JVM...
在Java应用程序运行过程中,经常会遇到“Out of Memory Error: Java Heap Space”的错误提示。这种错误通常发生在Java虚拟机(JVM)的堆内存不足时,导致程序无法继续运行。为了解决这一问题,本文将详细介绍如何...
标题中的“tomcat 解决Java heap space问题”指的是在运行Apache Tomcat服务器时,由于Java应用程序内存分配不当或资源消耗过大导致的“Java heap space”错误。这个问题通常出现在Java虚拟机(JVM)试图为对象分配...
### Java Heap Space 解决方法详解 #### 一、概述 在Java应用程序运行过程中,经常会遇到一个常见的错误提示:`java.lang.OutOfMemoryError: Java heap space`。这通常意味着Java虚拟机(JVM)的堆内存空间不足,...
这种错误通常表现为"Java heap space",意味着Java虚拟机(JVM)分配的内存不足以执行任务。 **Java堆空间的原理** Java堆是Java虚拟机中最大的一块内存区域,用于存储对象实例。当程序创建新的对象并分配给堆时,...
JAVA HeapAnalyzer
使用方法如下: ...python native_heapdump_viewer.py --symbols symbols 00.txt >00.log python native_heapdump_viewer.py --symbols symbols 01.txt >01.log 对比00.log和01.log,查看内存增长的点
Java heap space" 描述的是一个常见的Eclipse集成开发环境(IDE)中的问题,当用户尝试构建工作区时遇到内存不足的情况。这个错误表明Eclipse在执行任务时耗尽了Java虚拟机(JVM)分配的堆内存。以下是关于这个问题...
java虚拟机OutOfMemoryError:Java heap space堆dump文件,可以直接用来分析。
当堆内存不足以容纳新对象时,就会抛出java.lang.OutOfMemoryError: Java heap space错误。常见的解决方法是增加-Xmx参数值以扩大堆内存的大小。除此之外,还可能是由于代码问题导致内存消耗过大,例如内存泄漏或是...
### Java.lang.OutOfMemoryError:Java Heap Space 错误及处理办法 在Java应用程序开发与维护过程中,经常会遇到`java.lang.OutOfMemoryError: Java heap space`这一异常情况。该异常通常表明Java虚拟机(JVM)的堆...