簡體   English   中英

內存不足錯誤:內存可用時的Java堆大小

[英]Out of memory error: Java heap size when memory is available

我用java -Xmx240g mypackage.myClass運行java

操作系統是Ubuntu 12.10。

top表示MiB Mem 245743 total ,並且表明java進程從一開始就具有virt 254g MiB Mem 245743 total ,並且res正穩步增加到169g 在那一點上看起來它開始垃圾收集很多,我想是因為程序在那一點上是單線程的,並且CPU%在這一點上大多是100% ,並且此時它跳轉到1300-2000左右(我總結它是多線程垃圾收集器),然后res慢慢移動到172g 那時java崩潰了

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

new double[2000][5]

java -version

java version "1.7.0_15" OpenJDK Runtime Environment (IcedTea7 2.3.7) (7u15-2.3.7-0ubuntu1~12.10) OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)

硬件是亞馬遜cr1.8xlarge實例

在我看來,即使有大量可用內存,java也會崩潰。 這顯然是不可能的,我必須解釋一些錯誤的數字。 我應該在哪里了解發生了什么?

編輯:

我沒有指定任何GC選項。 唯一的命令行選項是-Xmx240g

我的程序成功地處理了許多輸入,而top有時表示它使用了高達98.3%的內存。 但是我用某些程序輸入重現了上述情況。

EDIT2:

這是科學的應用。 它有巨大的樹(1-10百萬個節點),每個節點有幾個大小的double陣列。 300x3 - 900x5。 初始樹創建程序后沒有分配太多內存。 大多數情況下,這些數組都會進行一些算術運算。

EDIT3:

HotSpot JVM以相同的方式死亡,在170-172g標記處使用了大量CPU並且出現了相同的錯誤。 看起來70-75%的內存是JVM不想跨越的神奇線條。

最終解決方案:使用-XX:+ UseConcMarkSweepGC -XX:NewRatio = 12程序通過170g標記,並且正在愉快地工作。

分析

您需要做的第一件事是獲取堆轉儲,以便在JVM崩潰時准確找出堆的樣子。 將這組標志添加到命令行:

-XX:+HeapDumpOnOutOfMemoryError -verbose:gc -XX:+PrintGCDetails

發生崩潰時,JVM會將堆寫入磁盤。 坦率地說,它需要花費很長時間才能達到這么大的規模。 如果您已經在運行Eclipse,請下載Eclipse MAT或安裝插件。 從那里,您可以加載堆轉儲並運行幾個預制報告。 你需要檢查泄漏嫌疑人和支配者樹,看看你的記憶力在哪里,並確定你沒有實際的泄漏。

之后,我建議您閱讀 Oracle關於垃圾收集的文檔 ,但是您可以考慮以下事項:

並發GC

-XX:+UseConcMarkSweepGC 

我從來沒有聽說有人在堆大小的堆上使用並行唯一的收集器。 您可以激活並發收集器,並且您將要閱讀增量模式並確定它是否適合您的工作負載/硬件組合。

堆自由比率

-XX:MinHeapFreeRatio=25

當您進行完整收集時,將其調低以降低垃圾收集器的欄。 這可能會阻止您執行完整集合時耗盡內存。 40%是默認值,嘗試使用較小的值。

新比率

-XX:NewRatio

我們需要更多地了解您的實際工作量:這是一個Web應用程序嗎? 搖擺應用程序? 根據預期對象在堆上保持活動的時間長短將對新比率值產生影響。 像你正在運行的服務器模式虛擬機默認情況下具有相當高的新比率(8:1),如果你有很多長期存在的對象,這可能不是你的理想選擇。

作為一般建議,從不使用OpenJDK,對生產環境來說更少,它比Sun / Oracle的要慢得多。

除此之外,我從未見過VM使用過多的內存,但我想這就是你需要的(或者你的代碼使用的內存比你需要的多?)

編輯:服務器的OpenJDK很好,只有與Sun / Oracle JDK的區別在於桌面內容(聲音,gui ......)所以忽略那部分。

如果我理解你的問題,看起來在程序遇到new double[2000][5]之前實際發生了內存泄漏。 當線路被擊中時,內存似乎已經很低,因此當該線路要求更多內存時它會拋出。

我會使用jvisualvm或類似的工具來找出內存泄漏的位置。 內存泄漏我遇到的主要是在循環中創建字符串,緩存未被清除等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM