6.1 Out of swap space? 概述
在啓動時, Java應用會分配有限的內存. 這個限制是通過-Xmx
和其他類似的啓動參數指定. 在這種場景: JVM申請的總內存大於可用的物理內存, 操作系統開始把這些內存從內存swap out到硬盤(分配到swap區).
java.lang.OutOfMemoryError: Out of swap space?
錯誤意味着swap區也耗盡, 新嘗試的分配由於物理內存和swap區的不足而導致失敗.
6.2 原因
當來自native heap的分配內存請求請求失敗, 且native heap接近用盡, JVM拋出java.lang.OutOfMemoryError: Out of swap space?
. 這消息表明分配內存大小失敗, 內存請求的原因.
該問題發生在這樣的場景: Java進程開始啓用swapping, 這已經不是一個好的情況了. 現在的GC策略很不錯, 但是當面臨由swapping引起的延遲問題, GC暫停會增加到大部分應用都服務法接受的級別.
java.lang.OutOfMemoryError: Out of swap space?
通常是由於操作系統層面的問題引起的, 例如:
- 操作系統swap區空間配置不足
- 系統上的另一個進程消耗了所有的內存資源
也有可能是因爲native泄漏導致的應用失敗, 例如, 如果應用或庫代碼持續消耗內存但是卻不釋放內存到操作系統.
6.3 解決方案
要克服這個問題, 你有幾種方案. 首先, 最常用的而且是最容易的方案是增加swap區. 這與平臺有關,例如在Linux中你可以使用下面的命令來實現,它創建並掛載一個新的swapfile —— 大小爲640 mb。
swapoff -a
dd if=/dev/zero of=swapfile bs=1024 count=655360
mkswap swapfile
swapon swapfile
現在,您應該回憶一下之前的內容,由於垃圾收集清除內存內容,一般來說,對於Java進程, 交換(swapping)是不受歡迎的。 在交換分配(swapped allocations)上運行垃圾收集算法會增加好幾個數量級的GC暫停時間,所以在跳到這個簡單解決方案的時候,你應該三思而後行。
如果您的應用程序部署在與需要競爭資源的“擾民惡鄰”的JVM的旁邊,那麼您應該將服務隔離到獨立的(虛擬的)機器上。
在許多情況下,您唯一真正可行的替代方案是升級機器以包含更多內存或優化應用程序以減少其內存佔用。當您轉向優化之路時,一個好的開始方法是使用內存轉儲(heap dump)分析程序來檢測內存中的大額分配。