使用Intellij idea 其發動tomcat時會配置啟動vm options :-Xms128m -Xmx768m -XX:PermSize=64M -XX:MaxPermSize=512m。
但是這些參數到底是什么意思呢? 有時候參數設置大小會出現內存泄漏的問題:
OOM(“Out of Memory”)異常一般主要有如下2種原因:
1. 年老代溢出,表現為:java.lang.OutOfMemoryError:Javaheapspace
這是最常見的情況,產生的原因可能是:設置的內存參數Xmx過小或程序的內存泄露及使用不當問題。
例如循環上萬次的字符串處理、創建上千萬個對象、在一段代碼內申請上百M甚至上G的內存。還有的時候雖然不會報內存溢出,卻會使系統不間斷的垃圾回收,也無法處理其它請求。這種情況下除了檢查程序、打印堆內存等方法排查,還可以借助一些內存分析工具,比如MAT就很不錯。
2. 持久代溢出,表現為:java.lang.OutOfMemoryError:PermGenspace
通常由於持久代設置過小,動態加載了大量Java類而導致溢出,解決辦法唯有將參數 -XX:MaxPermSize 調大(一般256m能滿足絕大多數應用程序需求)。將部分Java類放到容器共享區(例如Tomcat share lib)去加載的辦法也是一個思路,但前提是容器里部署了多個應用,且這些應用有大量的共享類庫。
參數說明
- -Xmx3550m:設置JVM最大堆內存為3550M。
- -Xms3550m:設置JVM初始堆內存為3550M。此值可以設置與-Xmx相同,以避免每次垃圾回收完成后JVM重新分配內存。
- -Xss128k:設置每個線程的棧大小。JDK5.0以后每個線程棧大小為1M,之前每個線程棧大小為256K。應當根據應用的線程所需內存大小進行調整。在相同物理內存下,減小這個值能生成更多的線程。但是操作系統對一個進程內的線程數還是有限制的,不能無限生成,經驗值在3000~5000左右。需要注意的是:當這個值被設置的較大(例如>2MB)時將會在很大程度上降低系統的性能。
- -Xmn2g:設置年輕代大小為2G。在整個堆內存大小確定的情況下,增大年輕代將會減小年老代,反之亦然。此值關系到JVM垃圾回收,對系統性能影響較大,官方推薦配置為整個堆大小的3/8。
- -XX:NewSize=1024m:設置年輕代初始值為1024M。
- -XX:MaxNewSize=1024m:設置年輕代最大值為1024M。
- -XX:PermSize=256m:設置持久代初始值為256M。
- -XX:MaxPermSize=256m:設置持久代最大值為256M。
- -XX:NewRatio=4:設置年輕代(包括1個Eden和2個Survivor區)與年老代的比值。表示年輕代比年老代為1:4。
- -XX:SurvivorRatio=4:設置年輕代中Eden區與Survivor區的比值。表示2個Survivor區(JVM堆內存年輕代中默認有2個大小相等的Survivor區)與1個Eden區的比值為2:4,即1個Survivor區占整個年輕代大小的1/6。
- -XX:MaxTenuringThreshold=7:表示一個對象如果在Survivor區(救助空間)移動了7次還沒有被垃圾回收就進入年老代。如果設置為0的話,則年輕代對象不經過Survivor區,直接進入年老代,對於需要大量常駐內存的應用,這樣做可以提高效率。如果將此值設置為一個較大值,則年輕代對象會在Survivor區進行多次復制,這樣可以增加對象在年輕代存活時間,增加對象在年輕代被垃圾回收的概率,減少Full GC的頻率,這樣做可以在某種程度上提高服務穩定性。
標准參數(-),所有JVM都必須支持這些參數的功能,而且向后兼容;例如:
- -client——設置JVM使用Client模式,特點是啟動速度比較快,但運行時性能和內存管理效率不高,通常用於客戶端應用程序或開發調試;在32位環境下直接運行Java程序默認啟用該模式。
- -server——設置JVM使Server模式,特點是啟動速度比較慢,但運行時性能和內存管理效率很高,適用於生產環境。在具有64位能力的JDK環境下默認啟用該模式。
- 非標准參數(-X),默認JVM實現這些參數的功能,但是並不保證所有JVM實現都滿足,且不保證向后兼容;
- 非穩定參數(-XX),此類參數各個JVM實現會有所不同,將來可能會不被支持,需要慎重使用;
