異常 - 虛擬機初始化錯誤 - Error occurred during initialization of VM


1 環境配置信息

1.1 服務器配置信息

服務器是物理機, 配置信息如下:

CPU型號 CPU個數 CPU核數 CPU線程數 內存
Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz 2個 2 * 10 = 20個核 2 * 20 = 40個線程 126G

1.2 Tomcat啟動參數

查看$TOMCAT_HOME/bin/catalina.sh文件, 其中JVM參數配置信息如下:

JAVA_OPTS="-server -Xms90g -Xmx90g -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC"

2 問題描述

在服務器(CentOS-6.5)中部署項目上線前的仿真測試環境, 啟動Tomcat時, 拋出如下錯誤:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

也就是: 初始化VM時出錯, 無法為heap(堆)對象保留足夠的空間.

錯誤: 無法創建Java虛擬機.

錯誤: 發生了致命異常. 程序將會退出.

3 問題解決

根據問題描述可知, Linux系統不允許初始化JVM時就申請這么大的內存.

(1) JVM可用內存測試方法:

# 配置好JDK的環境變量后, 在終端鍵入如下命令: 
java -Xmx32g -version

# 如果能夠正常顯示JDK的版本信息, 說明可以申請到指定大小的內存. 
# 若報錯, 說明申請的內存大小超出限制, 不被操作系統所允許. 

(2) 繼續查看系統資源限制情況:

# 在終端鍵入如下命令: 
ulimit -a
# 發現內存的使用並未受限: 
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited

經過排查, 原來某同事在測試Greenplum DB時, 修改了/etc/sysctl.conf文件中的系統內核參數.

# 將如下參數的值設置為1或0
vm.overcommit_memory=2

# 保存退出后, 使得更改生效: 
sysctl -p

此時再次啟動Tomcat, 發現啟動成功.

4 關於vm.overcommit_memory參數

vm.overcommit_memory表示系統內核在分配內存時做檢查的方式.

此參數有 [0、1、2] 3個值可選, 處理方式定義在內核源碼mm/mmap.c_vm_enough_memory函數中.

4.1 vm.overcommit_memory=0

默認設置. 宏為OVERCOMMIT_GUESS.

內核計算: NR_FILE_PAGES總量 + SWAP總量 + slab中可以釋放的內存總量, 如果申請空間超過此數值, 則將此數值與空閑內存總量減掉 totalreserve_pages() 的總量相加. 如果申請空間依然超過此數值, 則分配失敗.

該設置可能造成內存超載, 但也可以提升大量使用內存的任務的性能.

4.2 vm.overcommit_memory=1

宏為OVERCOMMIT_ALWAYS.

函數直接 return 0, 分配成功.

4.3 vm.overcommit_memory=2

宏為OVERCOMMIT_NEVER.

內核計算: 總物理內存 * vm.overcommit_ratio / 100 +SWAP總量, 如果申請空間超過此數值, 則分配失敗. vm.overcommit_ratio 默認值為50.

該設置可以有效減少內存過度使用的風險.

4.4 查看系統的可用內存

查看命令如下:

[root@localhost ~]# grep -i commit /proc/meminfo
CommitLimit:    66020980 kB
Committed_AS:   100135888 kB

其中:

CommitLimit: 當前系統還可以申請的總內存;

Committed_AS: 當前系統中所有應用申請了的總內存 —— 只是申請, 並未完全分配.

參考資料

linux 內存分配限制,overcommit_memory 2

sysctl 中 vm.overcommit_memory 的含義

版權聲明

作者: 馬瘦風

出處: 博客園 馬瘦風的博客

您的支持是對博主的極大鼓勵, 感謝您的閱讀.

本文版權歸博主所有, 歡迎轉載, 但請保留此段聲明, 並在文章頁面明顯位置給出原文鏈接, 否則博主保留追究相關人員法律責任的權利.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM