Java中JVM常用參數配置教程(提供配置示例)
前言
在實際開發(fā)和部署中一個合格的碼農都會對JVM的一些參數做合理的配置,比如內存配置參數、GC策略配置參數、日志配置參數、異常信息參數等,本文會列出一些常用的JVM參數以及通過一些例子演示配置后的效果。
PS:本文使用JDK1.8
一、內存參數配置
// 設置JVM使Server模式,特點是啟動速度較慢,但運行時性能和內存管理效率很高,適用于生產環(huán)境。在具有64位能力的JDK環(huán)境下默認啟用該模式。 -server // 設置元空間最大值, 默認是-1, 即不限制, 或者說只受限于本地內存大小,如果超過這個值會內存溢出。 -XX:MaxMetaspaceSize=256m // 指定元空間觸發(fā)Fullgc的初始閾值(元空間無固定初始大小), 以字節(jié)為單位,默認是21M,達到該值就會觸發(fā)full gc進行類型卸載, 同時收集器會對該值進行調整: 如果釋放了大量的空間, 就適當降低該值; 如果釋放了很少的空間, 那么在不超過-XX:MaxMetaspaceSize(如果設置了的話) 的情況下, 適當提高該值。這個跟早期jdk版本的-XX:PermSize參數意思不一樣,-XX:PermSize代表永久代的初始容量。 // 觸發(fā)一次元空間Full GC后就會重新計算該值,建議設置成和最大內存一致 -XX:MetaspaceSize=256m // 設置最大堆內存,默認是物理內存的1/4,內存的單位可以是m g,并且不區(qū)分大小寫 -Xmx2g 或者 -XX:MaxHeapSize=2048m // 設置初始值堆內存,默認是物理內存的1/64,內存的單位可以是m g,并且不區(qū)分大小寫 -Xms2g 或者 -XX:InitialHeapSize=2048m // 設置年輕代內存大小,默認和老年代1\2,-XX:NewSize初始化年輕代大小 -XX:MaxNewSize最大年輕代大小 -Xmn1g 或者 -XX:NewSize=1g -XX:MaxNewSize=1g // 設置每個線程的堆棧大小 默認是1024k,這個是最大內存并不是開啟一個線程馬上就會消耗這么多內存 -Xss512k 或者 -XX:ThreadStackSize=512k // 年輕代占用堆比例(如果有配置-Xmn,那么會以-Xmn配置為準) // 默認 -XX:NewRatio=2新生代占1,老年代占2,年輕代占整個堆的1/3 // 假如 -XX:NewRatio=4新生代占1,老年代占4,年輕代占整個堆的1/5 NewRatio值就是設置老年代的占比,剩下的1給新生代 -XX:NewRatio=2 // 用來設置新生代中eden空間和from/to空間的比例.含義:-設置為8代表 eden使用80%的新生代內存 from和to各用10%,默認為8 -XX:SurvivorRatio=8 // 禁用Survivor區(qū)自適應策略默認是開啟的,如果不關閉這個配置新生代eden區(qū)和s0 s1區(qū)會在gc后自動調整大小,如果設置了-XX:SurvivorRatio也只有在沒有GC之前有效只要GC后就會重新動態(tài)計算 -XX:-UseAdaptiveSizePolicy // 擴張堆內存的時機 // 堆內存使用率大于70時擴張堆內存,如果最大堆內存=初始堆內存時該參數無效,默認值70 -XX:MaxHeapFreeRatio=70 // 縮小堆內存的時機 // 堆內存使用率小于40時縮減堆內存,如果最大堆內存=初始堆內存時該參數無效,默認值40 -XX:MinHeapFreeRatio=40 // 字符串常量池hash桶大小 類似于HashTable,最小值1009 默認60013 不可動態(tài)擴容 -XX:StringTableSize=60013 // 設置直接內存大小,NIO(Non-blocking I/O)中通過ByteBuffer等對象分配的堆外內存 // 默認情況下,直接內存的大小可能會與Java堆的最大值 (-Xmx) 相同 -XX:MaxDirectMemorySize=512m
二、垃圾收集器配置
// 配置使用Serial單線程垃圾收集器,虛擬機運行在Client模式下的默認值 // 新生代使用Serial 老年代則使用SerialOld -XX:+UseSerialGC // 配置使用ParNew垃圾收集器 // 新生代使用ParNew 老年代則使用Serial Old -XX:+UseParNewGC // 配置使用Parallel Scavenge垃圾收集器,虛擬機運行在Server模式下的默認值 // 新生代使用Parallel Scavenge 老年代使用Parallel Old收集器 -XX:+UseParallelGC // 配置使用Parallel Old垃圾收集器 // 新生代使用Parallel Scavenge 老年代使用Parallel Old收集器 -XX:+UseParallelOldGC // 配置使用CMS垃圾收集器 // 新生代使用ParNew 老年代使用CMS+Serial Old收集器 -XX:+UseConcMarkSweepGC // 配置使用G1垃圾收集器 -XX:+UseG1GC
可以通過jinfo -flags 進程號
查看對應Java程序啟動參數,我本地使用的JDK1.8默認使用的ParallelGC
三、GC策略配置
3.1、基礎通用配置
// GC停頓時間,垃圾收集器會嘗試用各種手段達到這個時間,比如減小年輕代 -XX:MaxGCPauseMillis // 新生代晉升老年代閾值 默認是15 不同回收算法不同 -XX:MaxTenuringThreshold=15 // 對象動態(tài)年齡判斷默認50% 當一批對象大小>=survivor區(qū)的50%時這批對象會直接放入老年代 -XX:TargetSurvivorRatio=50 // 默認值是0沒有限制 大于這個值的參數直接在老年代分配 // 這樣做的目的是避免在Eden區(qū)和兩個Survivor區(qū)之間發(fā)生大量的內存復制 ‐XX:PretenureSizeThreshold=1m // 忽略手動調用GC, System.gc()的調用就會變成一個空調用,完全不觸發(fā)GC -XX:+DisableExplicitGC // 內存頁的大小 -XX:LargePageSizeInBytes=128m // 設定GMT區(qū)域,避免CentOS坑爹的時區(qū)設置 -Duser.timezone=GMT+8 // FullGC 前執(zhí)行MinorGC 默認是開啟的 -XX:+ScavengeBeforeFullGC
3.2、Parallel 和 Parallel Old 常用參數配置
// 調整垃圾回收的時間和總時間的占比 公式 1/(1+ratio) ratio默認是99,100分鐘運行時間默認不能超過1分鐘的GC時間,ratio一般設置為19 -XX:GCTimeRatio=99 // GC最大暫停毫秒數 默認是200毫秒 和-XX:+GCTimeRatio有沖突,堆內存小回收速度才會快,而-XX:+GCTimeRatio需要保證一定時間內GC時間不能超過一個臨界值需要增加內存才能減小GC時間比,需要找到一個兩個參數的合理值 -XX:MaxGCPauseMillis=200ms // 設置垃圾回收線程數量 默認是CUP內核數量 -XX:ParallelGCThreads=4
3.3、CMS 常用參數配置
// GC最大暫停毫秒數 默認是200毫秒 -XX:MaxGCPauseMillis=200ms // 為了加快此階段處理速度,減少停頓時間,可以開啟初始標記并行化 -XX:+CMSParallelInitialMarkEnabled // CMS并行線程數量,并行線程用于執(zhí)行 CMS 垃圾回收器的并行階段,如初始標記階段和重新標記階段 // 默認值為系統(tǒng)的邏輯處理器數量減1,目的是為了保留一個處理器用于應用程序線程 -XX:ParallelCMSThreads=3 // CMS并發(fā)線程數量,并發(fā)線程用于執(zhí)行 CMS 垃圾回收器的并發(fā)階段,如初始標記階段、并發(fā)標記階段和并發(fā)清理階段。 // 默認值為系統(tǒng)的邏輯處理器數量減1,目的是為了保留一個處理器用于應用程序線程 -XX:ConcGCThreads=3 // 執(zhí)行CMS的內存占比 percent=80 當我的老年代內存達到80%觸發(fā)垃圾回收 默認是92% 應為CMS采用標記清除需要給浮動垃圾(在最后一步并發(fā)清除時其它沒有被標記的垃圾遺留)預留空間 -XX:CMSInitiatingOccupancyFraction=percent // 該參數需要配合XX:CMSInitiatingOccupancyFraction使用,只使用設定的回收閾值(-XX:CMSInitiatingOccupancyFraction設 定的值),如果不指定,JVM僅在第一次使用設定值,后續(xù)則會自動調整 -XX:+UseCMSInitiatingOccupancyOnly // 重新標記階段前提前進行一次新生代GC,因為重新標記也會判斷新生代對象是否引用老年代對象,有些時候新生代對象已經沒有被GC root對象引用但是還沒有GC時,重新標記會掃描到新生代對象并且保留新生代對象引用的老年代對象,默認關閉false -XX:CMSScavengeBeforeRemark=true // 執(zhí)行完Full GC后對內存空間進行壓縮整理 默認開啟 -XX:+UseCMSCompactAtFullGollection // 設置在執(zhí)行多少次Full GC后對內存空間進行壓縮整理 默認0次,只要觸發(fā)Full GC就會進行內存壓縮 -XX:CMSFullGCsBeforeCompaction=0 // 垃圾回收時是否同時卸載不用的class信息,默認關閉 -XX:+CMSClassUnloadingEnabled
3.4、G1 常用參數配置
// 指定分區(qū)大小(1MB~32MB,且必須是2的N次冪),不設置默認會根據堆大小分配 // 堆內存為1G默認1024個1MB分區(qū)、堆內存為2G默認2048個1MB分區(qū)、堆內存為4G默認2048個2MB分區(qū)、堆內存為4G默認2048個2MB分區(qū)、堆內存為6G默認6144個1MB分區(qū)、堆內存為8G默認2048個4MB分區(qū)、以此類推 -XX:G1HeapRegionSize=2m // 目標暫停時間(默認200ms) -XX:MaxGCPauseMillis=200ms // 新生代內存初始空間(默認整堆5%) // PS: 因為JDK版本問題,在啟動時可能會出現(xiàn) "Error: VM option 'G1NewSizePercent' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions." // 如果出現(xiàn)上述問題,在啟動參數中添加-XX:+UnlockExperimentalVMOptions即可 -XX:G1NewSizePercent=5 // 新生代內存最大空間 (默認整堆60%) -XX:G1MaxNewSizePercent=60 // Survivor區(qū)的填充容量(默認50%),Survivor區(qū)域里的一批對象(年齡1+年齡2+年齡n的多個 年齡對象)總和超過了Survivor區(qū)域的50%,此時就會把年齡n(含)以上的對象都放入老年代 -XX:TargetSurvivorRatio=50 // 最大年齡閾值(默認15) -XX:MaxTenuringThreshold=15 // 老年代占用空間達到整堆內存閾值(默認45%),則執(zhí)行新生代和老年代的混合收集(MixedGC) -XX:InitiatingHeapOccupancyPercent=45 // region中的存活對象低于這個值時才會回收該region,如果超過這個值,存活對象過多,回收的的意義不大(默認65%)。 -XX:G1MixedGCLiveThresholdPercent=65 // 在一次回收過程中指定做幾次篩選回收(默認8次),在最后一個篩選回收階段可以回收一會,然后暫?;厥?,恢復系統(tǒng)運行,一會再開始回收,這樣可以讓系統(tǒng)不至于單次停頓時間過長。 -XX:G1MixedGCCountTarget=8 // gc過程中空出來的region是否充足閾值,在混合回收的時候,對Region回收都是基于復制算法進行的,都是把要回收的Region里的存活對象放入其他Region,然后這個Region中的垃圾對象全部清理掉,這樣的話在回收過程就會不斷空出來新的Region,一旦空閑出來的Region數量達到了堆內存的5%,此時就會立即停止混合回收,意味著本次混合回收就結束了(默認5%)。 -XX:G1HeapWastePercent=5
四、GC日志配置
// 設置日志目錄和日志名稱 -Xloggc:/data/logs/gc-%t.log // 開啟滾動生成日志 默認關閉 -XX:+UseGCLogFileRotation // 滾動GC日志文件數,默認0不滾動,保留最多5個日志文件 -XX:NumberOfGCLogFiles=5 // GC文件滾動大小,需開啟UseGCLogFileRotation,每個文件最大為20MB -XX:GCLogFileSize=20M // 在進行GC的前后打印出堆的信息 -XX:+PrintHeapAtGC // 打印新生代晉升詳情 -XX:+PrintTenuringDistribution // 打印字符串常量池堆信息 -XX:+PrintStringTableStatistics // 打印GC信息 -verbose:gc // 打印GC詳細信息 -XX:+PrintGCDetails // 輸出GC的時間戳(以基準時間的形式) -XX:+PrintGCTimeStamps // 輸出GC的時間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800) -XX:+PrintGCDateStamps // 打印當前JVM參數信息 建議在每個程序中都添加上 -XX:+PrintCommandLineFlags // 產生GC的原因(默認開啟) -XX:+PrintGCCause
五、dump 日志參數配置
5.1、OutOfMemory異常時生成dump文件
// 默認關閉 // 可以通過jinfo -flag [+|-]HeapDumpOnOutOfMemoryError <pid> 或 jinfo -flag HeapDumpOnOutOfMemoryError=<value> <pid> 來動態(tài)開啟或設置值 -XX:+HeapDumpOnOutOfMemoryError // 設置文件存儲路徑 // 當HeapDumpOnOutOfMemoryError開啟的時候,dump文件的保存路徑,默認為工作目錄下的,可以通過配置指定保存路徑 -XX:HeapDumpPath=/data/dump/jvm.hprof
5.2、發(fā)生Full GC時生成dump文件
不推薦開啟會增加整體停頓時間
// 在Full GC前dump -XX:+HeapDumpBeforeFullGC // 在Full GC后dump -XX:+HeapDumpAfterFullGC // 設置Dump保存的路徑 -XX:HeapDumpPath=/data/dump/jvm.hprof
六、其它參數配置
// JVM自身故障導致進程奔潰時,會有一個日志文件生成,它包含了導致crash的重要信息,通過分析文件來查找crash原因 -XX:ErrorFile=/data/logs/error.log // JDK1.6開始,默認server模式下開啟了這個參數,意為當jvm檢測到程序在重復拋一個異常 // 在執(zhí)行若干次后會將異常吞掉,這里的若干次在jdk1.7測得是20707。即執(zhí)行20707次后,stackTrace 長度會為0。有時這不利于我們排錯,通過指定OmitStackTraceInFastThrow,可禁用這功能 -XX:-OmitStackTraceInFastThrow
七、配置示例
需要配置的參數信息
// 配置新生代使用Parallel Scavenge 老年代將會使用Parallel Old收集器 -XX:+UseParallelOldGC // 配置元空間最大內存和初始內存 -XX:MaxMetaspaceSize=256m -XX:MetaspaceSize=256m // 配置最大堆內存、初始內存、新生代占用內存 -Xmx512m -Xms512m -Xmn256m // 配置關閉動態(tài)調整新生代eden和from to大小比例 -XX:-UseAdaptiveSizePolicy // 配置忽略手動調用GC和時區(qū) -XX:+DisableExplicitGC -Duser.timezone=GMT+8 // 配置開啟記錄OOM Dump信息和存儲地址 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./jvm.hprof // 配置打印當前JVM參數信息 -XX:+PrintCommandLineFlags // 配置開啟GC日志輸出 -verbose:gc -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCDateStamps -Xloggc:./gc-%t.log // 配置關閉重復多次拋同一個異常不輸出 -XX:-OmitStackTraceInFastThrow // 配置JVM自身故障導致宕機時日志輸出目錄 -XX:ErrorFile=./error.log
7.1、在IDEA中配置JVM參數
- 配置參數(注意文件的輸出目錄,我這里會直接輸出在當前目錄)
-XX:+UseParallelOldGC -XX:MaxMetaspaceSize=256m -XX:MetaspaceSize=256m -Xmx20m -Xms20m -Xmn10m -XX:-UseAdaptiveSizePolicy -XX:+DisableExplicitGC -Duser.timezone=GMT+8 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./jvm.hprof -XX:+PrintCommandLineFlags -verbose:gc -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCDateStamps -Xloggc:./gc-%t.log -XX:-OmitStackTraceInFastThrow -XX:ErrorFile=./error.log
- 配置流程
7.2、通過 Java -jar 啟動配置
# 應用配置示例 nohup java -XX:+UseParallelOldGC -XX:MaxMetaspaceSize=256m -XX:MetaspaceSize=256m -Xmx512m -Xms512m -Xmn256m -XX:-UseAdaptiveSizePolicy -XX:+DisableExplicitGC -Duser.timezone=GMT+8 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./jvm.hprof -XX:+PrintCommandLineFlags -verbose:gc -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCDateStamps -Xloggc:./gc-%t.log -XX:-OmitStackTraceInFastThrow -XX:ErrorFile=./error.log -jar app.jar > app.log 2>&1 &
總結
到此這篇關于Java中JVM常用參數配置的文章就介紹到這了,更多相關Java JVM常用參數配置內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot整合Sa-Token實現(xiàn)登錄認證的示例代碼
本文主要介紹了SpringBoot整合Sa-Token實現(xiàn)登錄認證的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01SpringMVC4+MyBatis+SQL Server2014實現(xiàn)數據庫讀寫分離
這篇文章主要介紹了SpringMVC4+MyBatis+SQL Server2014實現(xiàn)讀寫分離,需要的朋友可以參考下2017-04-04Spring Boot集成Mybatis的實例代碼(簡潔版)
這篇文章主要介紹了Spring Boot集成Mybatis簡潔版的教程,需要的朋友可以參考下2018-02-02解析SpringBoot中@Autowire注解的實現(xiàn)原理
在開發(fā)Java項目時,依賴注入是一種常見的實現(xiàn)方式,SpringBoot框架通過@Autowired注解來實現(xiàn)依賴注入的功能,本文將介紹SpringBoot中 Autowired注解實現(xiàn)的原理2023-06-06