Garbage Collector(GC)自動管理應用程序的動態(tài)內(nèi)存分配請求
垃圾收集器通過以下操作執(zhí)行自動動態(tài)內(nèi)存管理:
- 從操作系統(tǒng)申請內(nèi)存并將內(nèi)存返回給操作系統(tǒng)
- 在應用程序請求時將內(nèi)存分發(fā)給應用程序
- 確定應用程序仍在使用該內(nèi)存的哪些部分
- 回收未使用的內(nèi)存以供應用程序重用
Java HotSpot垃圾收集器采用各種技術來改進這些操作的效率:
- 將分代清理(generational scavenging)與年齡(aging)結(jié)合使用旺垒,將精力集中在堆中最可能包含大量可回收內(nèi)存的區(qū)域
- 使用多個線程并行操作,或者在后臺與應用程序并發(fā)執(zhí)行需要長運行時間的操作
- 嘗試通過整理(compacting, 壓實)存活的對象來恢復更大的連續(xù)內(nèi)存
虛擬機內(nèi)程序計數(shù)器巍佑、虛擬機棧、本地方法棧3個運行時數(shù)據(jù)區(qū)是線程私有的內(nèi)存區(qū)域瞬逊,內(nèi)存分配回收都比較確定哎媚,隨著方法和線程的結(jié)束占遥,回收內(nèi)存,而堆和方法區(qū)是線程共享的存儲區(qū)域瞻讽,內(nèi)存的分配和回收是動態(tài)的鸳吸,是GC處理的核心
Java 11 GC Tuning Guide 文檔:
Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide, Release 11
Java 9 和11中GC,堆大小速勇,及時編譯的默認設置:
- 使用Garbage-First (G1) collector (Java 7 和 8 默認是 Parallel GC)
- GC 線程的最大值受堆大小和可獲得的CPU資源限定
- 初始堆大小為物理內(nèi)存的 1/64
- 堆的最大值默認是物理內(nèi)存的 1/4
- 分層編譯Tiered compiler, 同時使用 C1 and C2編譯器
基于行為的調(diào)優(yōu)
在行為上晌砾,GC主要有兩個不同的目標,一個是控制GC的最長停頓時間烦磁,使得響應更加及時养匈,另一個方面是控制吞吐量,使得GC時間占比較小都伪,Java HotSpot VM GC 可以配置為優(yōu)先滿足這兩個目標之一呕乎,如果滿足首選目標,GC會嘗試最大化另一個目標陨晶,因為堆內(nèi)存大小的限制猬仁,以及其他的配置的影響,也存在GC不能滿足目標的可能
最大暫停時間 Maximum Pause-Time
暫停時間是垃圾收集器停止應用并回收不再使用的內(nèi)存空間的持續(xù)時間先誉,-XX:MaxGCPauseMillis=<n>
用來限制暫停的最長時間湿刽,不同GC的默認值不同,調(diào)整得過小可能導致垃圾收集更頻繁地發(fā)生褐耳,從而降低應用程序的整體吞吐量
GC會記錄平均停頓時間和相對平均值的偏差诈闺,如果平均值加上暫停時間的偏差大于目標值,則目標停頓時間未滿足
吞吐量 Throughput
吞吐量是根據(jù)GC所花費和在垃圾收集之外花費的時間application time來衡量的铃芦,由-XX:GCTimeRatio=nnn
指定雅镊。垃圾收集時間與應用時間的比率為1/ (1+nnn)
襟雷,例如书斜,-XX:GCTimeRatio=19
設置垃圾收集為總時間的1/20或5%懦砂。
垃圾收集所花費的時間是所有垃圾收集引起的暫停的總時間悼沿。如果未滿足吞吐量目標凫岖,則GC可能會增加堆的大小,以便在兩次GC停頓時間之間在應用時間更長
內(nèi)存占用
如果已滿足吞吐量和最大暫停時間的設定浮声,則垃圾收集器會減小堆大小怨咪,直到無法滿足其中的吞吐量目標×欧梗可以使用-Xms=<nnn>
和-Xmx=<mmm>
分別設置GC可以使用的最小和最大堆大小
優(yōu)化策略
- 除非知道需要的堆空間大于默認最大堆大小(物理內(nèi)存的四分之一),否則不要為堆設定最大值
- 應用程序行為的改變會導致堆增長或縮小胧砰。例如鳍鸵,如果應用以更高的速率分配空間,則堆空間需要增長來保持相同的吞吐量
- 如果堆增長到其最大大小并且未滿足吞吐量目標尉间,則最大堆大小對于吞吐量目標而言太小偿乖。可以將最大堆大小設置為接近物理內(nèi)存的值
- 如果可以滿足吞吐量目標哲嘲,但暫停時間過長贪薪,設定最大暫停時間,吞吐量可能目標無法滿足眠副,因此需要選擇一個可接受的折中值
判斷對象是否存活
GC回收堆內(nèi)存空間之前首先要判斷對象是否存活
引用計數(shù)算法 Reference Counting
每個對象都有一個引用計數(shù)器画切,有引用的地方就加1,引用失效的時候就減1囱怕,為0就可以回收
問題:很難解決對象之間的相互循環(huán)引用的問題可達性分析算法 Reachability Analysis
如果程序中的任何其他存活對象的引用無法再訪問它霍弹,對象被認為是垃圾,此時VM可以重用它的內(nèi)存娃弓,通過一系列稱為GC Roots
的對象作為起始點典格,從這些節(jié)點開始向下搜索,搜索所有走過的路徑稱為引用鏈Reference Chain
台丛,當一個對象到GC Roots沒有任何引用鏈相連時耍缴,說明對象不可用
GC Roots對象的種類
- 虛擬機棧中引用的對象 Local variables
- 方法區(qū)類靜態(tài)屬性或常量引用的對象 Static variables
- 本地方法棧中JNI引用的對象
引用
一個對象的引用,根據(jù)引用強度的強弱挽霉,分為四種防嗡,GC時根據(jù)不同的情況,決定是否回收對應類型對象的內(nèi)存空間
強引用 Strong Reference
默認的引用類型,只要存在強引用炼吴,GC就不會回收引用的對象本鸣,默認創(chuàng)建都是強引用類型軟引用 Soft Reference
當虛擬機內(nèi)部不足,拋出OutOfMemoryError
之前硅蹦,GC會清除這些對象的內(nèi)存荣德,通常用于實現(xiàn)對內(nèi)存敏感的緩存闷煤,內(nèi)存不足會自動清除
SoftReference<User>softReference=new SoftReference<User>(new User());
-
弱引用 Weak Reference
非必須的對象,當垃圾收集器工作時涮瞻,無論內(nèi)存是否足夠鲤拿,都會回收掉只被弱引用關聯(lián)的對象
WeakReference<User> weakBuilder = new WeakReference<User>(new User());
-
虛引用 Phantom Reference
無法通過虛引用獲取一個對象的實例,get()
方法返回始終為NULL
唯一目的就是在這個對象回收時收到一個系統(tǒng)通知署咽,例如在NIO的DirectByteBuffer
內(nèi)進行native內(nèi)存釋放的Cleaner
類
package jdk.internal.ref;
public class Cleaner
extends PhantomReference<Object>
-
ReferenceQueue
在檢測到適當?shù)目傻竭_性更改后近顷,垃圾回收器將已注冊的引用對象添加到該隊列中,內(nèi)部事先由GC組成一個PendingList宁否,然后通過在Reference
類初始化時窒升,靜態(tài)塊內(nèi)部創(chuàng)建的ReferenceHandler
線程將其取出加入到引用隊列中
引用對象的狀態(tài)由兩個屬性表征:
最開始處于Active
狀態(tài),當Reference對應的對象可以被垃圾收集器回收時慕匠,GC會將該Reference的狀態(tài)轉(zhuǎn)換為Pending
饱须,經(jīng)過ReferenceHandler處理后轉(zhuǎn)變?yōu)?code>Inactive
clear/enqueue/GC
[active/unregistered] ------
| |
| GC |
| |--> [inactive/unregistered]
v |
[pending/unregistered] ------
ReferenceHandler
如果Reference對象創(chuàng)建時指定了ReferenceQueue
則對應狀態(tài)為Registered
,GC將其加入到PendingList台谊,ReferenceHandler將其讀取出來蓉媳,加入引用隊列后狀態(tài)轉(zhuǎn)變?yōu)?code>Enqueued,用戶線程調(diào)用ReferenceQueue.remove()
函數(shù)阻塞式獲取隊列中的對象锅铅,來獲知某個引用要被回收酪呻,這相當于一種通知機制,從隊列中取出后狀態(tài)轉(zhuǎn)變?yōu)?code>Dequeued
內(nèi)部具體實現(xiàn)上盐须,當加入ReferenceQueue
之后玩荠,引用對象中的隊列信息ReferenceQueue<? super T> queue
會被自動覆蓋為NULL,下次GC需要回收時就無法再次加入引用隊列丰歌,內(nèi)存空間會被直接回收
clear
[active/registered] -------> [inactive/registered]
| |
| | enqueue [2]
| GC enqueue [2] |
| -----------------|
| |
v |
[pending/registered] --- v
| | ReferenceHandler
| enqueue [2] |---> [inactive/enqueued]
v | |
[pending/enqueued] --- |
| | poll/remove
| poll/remove |
| |
v ReferenceHandler v
[pending/dequeued] ------> [inactive/dequeued]
Reference
時創(chuàng)建時姨蟋,附加一個引用隊列參數(shù)
Reference(T referent, ReferenceQueue<? super T> queue)
FinalReference
實現(xiàn)Object的finalize()
方法的類,在創(chuàng)建對象的時立帖,JVM會實例化一個對應的FinalReference
Finalizer
Finalizer是FinalReference的子類眼溶,該類被final修飾,不可再被繼承晓勇,JVM實際操作的是Finalizer類堂飞,當滿足實例化FinalReference的條件時,JVM會調(diào)用Finalizer.register(Object finalizee)
進行注冊绑咱,對應的引用隊列是Finalizer
類內(nèi)部的靜態(tài)變量private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
绰筛,靜態(tài)塊中的初始化的FinalizerThread
線程從引用隊列中取出元素,執(zhí)行其finalize()
方法
方法區(qū)的回收
Permanent generation(方法區(qū))存儲描述類和方法的元數(shù)據(jù)描融,需要回收兩個部分的內(nèi)存:廢棄常量和無用的類
其中無用的類需要同時滿足以下三個條件:
- 類的所有實例已經(jīng)被回收
- 加載該類的ClassLoader 已經(jīng)被回收
- 該類的
java.lang.Class
對象沒有再任何地方被引用铝噩,后續(xù)不會通過反射的方式訪問該類
垃圾收集算法基礎
性能考慮
GC主要關注兩點,吞吐量和延遲
- 吞吐量是一段長時間周期內(nèi)不考慮的GC的時間占總時間的百分比窿克,吞吐量包括分配內(nèi)存所花費的時間(但通常不需要調(diào)優(yōu)內(nèi)存分配速度)
- 延遲是應用程序的響應能力骏庸,GC暫停會影響應用程序的響應能力毛甲。
標記 - 清除 Mark-Sweep
首先對所有需要回收的對象進行標記,后來統(tǒng)一回收
這是最基礎的收集算法具被,后續(xù)的收集算法都是基于這種思路玻募,并對其不足進行改進而得到的
不足:
- 效率不高
- 空間問題,產(chǎn)生大量不連續(xù)的碎片
標記 - 整理 Mark-Compact
讓所有存活對象向一端移動一姿,然后直接清理掉端邊界以外的內(nèi)存
分代收集 Generational Collection
理論上七咧,最直接的垃圾收集算法每次運行時遍歷每個可到達的對象,任何剩余的對象都被認為是垃圾叮叹。這種方法所花費的時間與活動對象的數(shù)量成正比艾栋,這對于維護大量實時數(shù)據(jù)的大型應用程序來說是不可行的
Java HotSpot VM包含許多不同的垃圾收集算法,這些算法都使用稱為分代收集 generational collection 的技術衬横。分代收集利用幾條對大多數(shù)應用程序的經(jīng)驗觀測屬性來最小化回收未使用(垃圾)對象所需的工作裹粤。其中最重要屬性是是弱分代假說 weak generational hypothesis,它表明大多數(shù)對象都只能存活很短的時間
堆區(qū)根據(jù)對象存活周期的不同將內(nèi)存分為幾塊蜂林,例如新生代和老年代,區(qū)域填滿時采用不同的收集算法
最開始拇泣,JVM會保留整個Java堆的地址空間噪叙,但是只有在需要的時候才分配物理內(nèi)存
Young Generation
對象填滿時,觸發(fā) minor collection 回收該區(qū)域霉翔,時間復雜度與活動對象的數(shù)量成比例睁蕾,通常每次會有部分幸存對象移動到Old Generation
,當它填滿時觸發(fā) major collection 進行回收债朵,清理整個堆區(qū)域子眶,通常所需的時間更長,因為涉及更多的對象
復制算法 Copying
新生代代由Eden
和兩個Survivor
空間組成序芦,大多數(shù)對象最初都是在Eden
中分配的臭杰,在任何時候必然由一個Survivor
空間是空的,在GC期間充當Eden
和另一個Survivor
空間中存活對象的目的地谚中;GC之后渴杆,Eden
和源Survivor
空間都是空的。在下一次GC中宪塔,兩個Survivor
空間的用途互換了磁奖。最近被填充的一個作為源Survivor
,將其中的存活對象復制到另一個Survivor
空間某筐。 對象以這種方式在兩個Survivor
之間復制比搭,直到它們被復制了一定次數(shù)或者沒有足夠的空間,此時這些對象將被復制到老年代中(這個過程叫做aging)
新生代和老年代的晉升
每個對象在新生代有個年齡值南誊,如果經(jīng)歷一次minor gc蜜托,對應的年齡就會增加同廉,達到閾值(-XX:MaxTenuringThreshold=n
設定蟆湖,n的最大值為15,parallel collector 默認15结窘,CMS 默認為6),即可晉升,移動到老年代
如果Survivor空間中相同年齡所有對象大小之和大于Survivor空間的一半派草,年齡大于或者等于該年齡的對象可以直接進入年老代歧譬,無需達到閾值的要求
術語:
full GC:清理整個Java 堆區(qū)
Stop the World Event : JVM上所有的應用都停止缩焦,直到gc操作完成,無論哪種gc算法嵌赠,無論是新生代還是老年代都會產(chǎn)生STW
影響垃圾收集性能的因素
兩個最重要的因素是總可用內(nèi)存和新生代在堆中的比例
堆空間總量 Total Heap
這是影響垃圾收集性能的最重要因素袜炕,因為GC在對應分代的內(nèi)存填滿時發(fā)生
在初始化虛擬機時,保留堆的整個空間初家,-Xmx
選項指定保留空間的大小,如果-Xms
參數(shù)的值小于-Xmx
參數(shù)的值乌助,則不會將所有保留的空間立即交給虛擬機溜在,未提交的空間在圖中標記為virtual
,隨后堆的不同分區(qū)他托,可以根據(jù)需要向虛擬空間增長
新生代比例
新生代越大掖肋,發(fā)生的minor collection
就越少,但是赏参,堆大小本身是有限的志笼,新生代比例較大意味著老年代比例較小,這將增加major collection
的頻率把篓,最佳比例取決于程序內(nèi)對象的生命周期分布纫溃,設定-XX:NewSize=size
,-XX:MaxNewSize=size
韧掩,-XX:NewRatio=ratio
其中如果survivor
空間太小紊浩,那么復制收集算法會將數(shù)據(jù)溢出到老年代,如果太大,浪費空間坊谁,設定-XX:SurvivorRatio=ratio
垃圾收集器
JDK 9 到 目前(JDK 11)费彼,Java HotSpot VM包括三種不同類型的收集器,每種收集器具有不同的性能特征
Serial Collector (-XX:+UseSerialGC)
串行收集器使用單個線程來執(zhí)行所有垃圾收集工作口芍,這使得它相對有效箍铲,因為線程之間沒有通信開銷,它最適合單處理器機器鬓椭,因為它無法利用多處理器硬件颠猴,也適用于多處理器上的小型應用程序(內(nèi)存大小為100MB左右)
使用選項-XX:+UseSerialGC
顯式啟用串行收集器,使用分代收集的原理膘融,新生代使用復制算法芙粱,老年代使用標記整理算法
Parallel Collector (-XX:+UseParallelGC)
并行收集器也稱為吞吐量收集器throughput collector
,它是類似于串行收集器的分代收集器氧映。串行和并行收集器之間的主要區(qū)別在于并行收集器具有多個線程春畔,用于加速垃圾收集。
并行收集器適用于運行在多處理器或多線程硬件上的具有中到大型數(shù)據(jù)集的應用程序岛都,使用-XX:+UseParallelGC
選項啟用律姨,新生代使用parallel scavenge garbage collector
,老年代parallel garbage collector
臼疫,如果啟動-XX:+UseParallelGC
選項择份,會默認啟動-XX:+UseParallelOldGC
設定,反之亦然
可以使用-XX:ParallelGCThreads=<N>
來控制垃圾收集器線程的數(shù)量烫堤。因為多個垃圾收集器線程參與minor collection
荣赶,在收集期間從新生代晉升(promotion
)到老年代可能產(chǎn)生一些碎片。minor collection
中的每個垃圾收集線程都會保留老年代的一部分用于晉升鸽斟,將可用空間劃分為“晉升緩沖區(qū)”會導致碎片效應拔创,減少垃圾收集器線程的數(shù)量并增加老年代的大小可以減少這種碎片效應
并行收集器目標的優(yōu)先級:當同時設定由最大暫停時間目標,吞吐量目標和最小內(nèi)存目標時富蓄,首先滿足最大暫停時間目標剩燥,之才是吞吐量目標,最后是內(nèi)存目標
如果超過98%的總時間花在垃圾收集上并且不到2%的堆空間被回收立倍,則拋出OutOfMemoryError
灭红,防止應用程序長時間運行,但由于堆太小進度很慢口注。也可以通過-XX:-UseGCOverheadLimit
來禁用此功能
ParNew (-XX:+UseParNewGC)/ CMS (-XX:+UseConcMarkSweepGC)
ParNew GC在新生代中使用多線程進行垃圾收集变擒,與用于清理老年代的CMS算法配合使用
當設定-XX:+UseConcMarkSweepGC
時自動使用,在JDK 8中-XX:+UseParNewGC
必須和-XX:+UseConcMarkSweepGC
配合使用疆导,選項組合-XX:+UseConcMarkSweepGC -XX:-UseParNewGC
已經(jīng)棄用赁项,從JDK 9開始葛躏,棄用-XX:+UseParNewGC
選項
Concurrent Collectors
Concurrent Mark Sweep (CMS)和 Garbage-First (G1) 垃圾收集器是兩個主要的并發(fā)收集器,并發(fā)收集器在執(zhí)行一些昂貴的工作時與應用程序并發(fā)運行
- G1垃圾收集器:服務器式收集器悠菜,適用于具有大量內(nèi)存的多處理器計算機舰攒。 它有很高的概率滿足垃圾收集停頓時間的要求,同時實現(xiàn)高吞吐量悔醋,很多參數(shù)可以自適應調(diào)節(jié)摩窃,使用簡單高效。Java 9 開始默認使用G1芬骄,可以使用
-XX:+UseG1GC
顯式啟用G1 - CMS收集器:適用于需要較短垃圾收集暫停且可以與GC共享處理器資源的應用程序猾愿,使用選項
-XX:++UseConcMarkSweepGC
啟用CMS收集器,從JDK 9開始账阻,CMS收集器已經(jīng)被棄用
并發(fā)收集器交換處理器資源(否則可供應用程序使用)以縮短主要收集暫停時間蒂秘。
最明顯的開銷是在GC的并發(fā)部分會使用一個或多個處理器,在N處理器系統(tǒng)上淘太,并發(fā)部分使用可用處理器的 K/N姻僧,其中1 <= K <= ceiling{N/4}
。除了在并發(fā)階段使用處理器之外蒲牧,還會產(chǎn)生額外的開銷以實現(xiàn)并發(fā)撇贺。因此,雖然并發(fā)收集器的垃圾收集暫停通常要短得多冰抢,但應用程序吞吐量也往往略低于其他收集器
在多核的計算機上松嘶,應用程序線程在并發(fā)部分期間依然可以獲得處理器,因此并發(fā)垃圾收集器線程不會暫停應用程序挎扰,使得暫停時間縮短翠订,但應用程序可用的處理器資源也會減少,并且應該會有一些減速遵倦,特別是如果應用程序最大限度地使用所有核蕴轨。隨著N的增加,由于并發(fā)垃圾收集導致的處理器資源的減少變得更小骇吭,并發(fā)收集的益處也會增加
Z Garbage Collector
Z垃圾收集器 (ZGC) 是一個可擴展的低延遲垃圾收集器。 ZGC并發(fā)式的執(zhí)行所有昂貴的工作歧寺,不需要停止執(zhí)行應用線程
ZGC適用于需要低延遲(小于10毫秒暫停)和/或使用非常大的堆(TB量級)的應用燥狰,使用-XX:+UseZGC
啟用,從JDK 11開始斜筐,ZGC作為實驗性功能提供
選擇合適的GC
如有必要龙致,先調(diào)整堆大小來提高性能。如果性能仍不符合要求
- 如果應用程序具有較小的數(shù)據(jù)集(最大約100 MB)或者在單個處理器上運行且沒有暫停時間要求顷链,則選擇串行收集器
-XX:+UseSerialGC
- 如果應用程序的極限性能是第一優(yōu)先級考慮并且沒有暫停時間要求目代,或者可以接收一秒或更長的暫停時間,那么可以讓VM選擇收集器或選擇并行收集器
-XX:+UseParallelGC
- 如果響應時間比總吞吐量更重要,并且垃圾收集暫停必須保證短于一秒左右榛了,那么選擇并發(fā)收集器
-XX:+UseG1GC
或-XX:+UseConcMarkSweepGC.
- 如果響應時間是高優(yōu)先級在讶,和/或使用的是非常大的堆內(nèi)存,選擇完全并發(fā)的收集器
-XX:+UseZGC
此外性能還取決于堆的大小霜大,應用程序內(nèi)的實時數(shù)據(jù)量以及處理器的數(shù)量和速度构哺,如果推薦的收集器未達到所需性能,則首先嘗試調(diào)整堆和分代的大小战坤。如果性能仍然不足曙强,那么嘗試使用不同的收集器:使用并發(fā)收集器來減少暫停時間,使用并行收集器來提高多核處理器的總吞吐量
參數(shù)配置
選項
-X
:非標準選項(不保證所有的 JVM 實現(xiàn)都支持)
-XX
:不穩(wěn)定途茫、不建議隨便使用
- 布爾選項 打開
-XX:+<option>
碟嘴,關閉-XX:-<option>
- 數(shù)值選項 設定方式
-XX:<option>=<number>
,數(shù)字可以包含 'm' 'M' , 'k' 'K' f, 'g' 'G' - 字符串選項 設定
-XX:<option>=<string>
查詢某個參數(shù)的默認值囊卜,例如MaxHeapSize
的值
> java -XX:+PrintFlagsFinal -version | grep MaxHeapSize
uintx MaxHeapSize := 4173332480 {product}
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
選項 | 描述 |
---|---|
堆椖壬龋空間相關 | |
-Xms -Xmx | 堆的最小值和最大值,對于服務器的部署边败,通常設定為相同的值,避免堆大小調(diào)整產(chǎn)生的暫停 |
-Xss | 設定線程調(diào)用棧的大小袱衷,默認是1M,默認操作系統(tǒng)ulimit -s 限定最大為8192KB |
-Xmn | 新生代的大小笑窜,直接設定為固定值致燥,可以通過-XX:NewSize 和-XX:MaxNewSize 分別設定初始大小和最大值 |
-XX:MaxHeapFreeRatio | GC后堆空間的最大空閑比例(默認70%,達到會進行收縮)排截,調(diào)小會減小內(nèi)存占用 |
-XX:MinHeapFreeRatio | GC后堆空間的最小空閑比(默認40%嫌蚤,不足堆空間會進行擴張),調(diào)小會減少內(nèi)存占用 |
-XX:-ShrinkHeapInSteps | 默認情況下開啟断傲,逐步減小堆空間到最大空閑比脱吱,關閉會立即減小,可能導致性能下降 |
GC類型 | |
-XX:+UseG1GC | 使用G1收集器 |
-XX:+UseSerialGC | 使用Serial GC |
-XX:+UseParallelGC | 使用 Parallel Scavenge GC |
-XX:+UseParallelOldGC | 使用 Parallel Old GC |
-XX:+UseParNewGC | deprecated认罩,JDK 9 |
-XX:+UseConcMarkSweepGC | deprecated箱蝠,JDK 9 |
GC性能設定 | |
-XX:MaxGCPauseMillis=n | 設定最長停頓時間,毫秒 |
-XX:GCTimeRatio=n | 吞吐量設定垦垂,1 / (1 + n) 宦搬,G1默認為12,GC時間占比8% |
-XX:ParallelGCThreads=n | 設置STW工作線程的值劫拗,邏輯處理器的數(shù)量不超過8時间校,n的默認值與邏輯處理器的數(shù)量相同,如果有超過8個邏輯處理器页慷,n默認值為邏輯處理器數(shù)量的5/8 |
新生代相關 | |
-XX:NewRatio=n | young : old = 1 : n 憔足,默認n為2 |
-XX:NewSize | 新生代的初始大小胁附,推薦為堆大小的25%到50% |
-XX:MaxNewSize | 新生代的最大值 |
-XX:SurvivorRatio=n | eden/survivor區(qū)域的比例,默認為8滓彰,即每個survivor占新生代的1/10控妻,默認-XX:+UseAdaptiveSizePolicy 是開啟的,JVM會動態(tài)調(diào)整survivor的大小比例找蜜,最小為3 |
-XX:MaxTenuringThreshold=n | 對象晉升老年代的年齡閾值饼暑,parallel gc默認15,CMS默認為6 |
G1相關設置 | |
-XX:G1HeapRegionSize | 堆區(qū)域的大小洗做,默認基于初始和最大堆大小得到弓叛,在1到32 MB之間變化,并且必須是2的冪诚纸,堆包含大約2048個堆區(qū)域 |
-XX:InitialHeapOccupancyPercent | 默認整個堆占比45%時觸發(fā)并發(fā)標記 |
-XX:ConcGCThreads | 并發(fā)標記的線程數(shù)目撰筷,ParallelGCThreads的 1/4 |
-XX:+G1UseAdaptiveIHOP -XX:InitiatingHeapOccupancyPercent=45 | 用于自適應控制啟動并發(fā)標記的堆占用百分比,對于前幾個收集周期G1將使用老年代的45%的占用率作為默認閾值 |
-XX:G1NewSizePercent=5 -XX:G1MaxNewSizePercent=60 | 新生代的大小畦徘,在這兩個值之間變化毕籽,百分比表示占當前使用的Java堆的比例 |
-XX:G1HeapWastePercent=5 | 區(qū)域集合中允許未回收空間百分比,如果收集集合候選中的可回收空間低于該閾值井辆,則G1將停止空間回收階段 |
-XX:G1MixedGCCountTarget=8 | 空間回收階段的進行收集的次數(shù) |
-XX:G1MixedGCLiveThresholdPercent=85 | 老年代區(qū)域的存活對象大于該比例关筒,不會在空間回收階段進行垃圾收集 |
CMS設置 | |
-XX:CMSInitiatingOccupancyFraction | 設置啟動CMS的老年代占用率,默認值為-1杯缺,使用-XX:CMSTriggerRatio 的值 |
-XX:CMSTriggerRatio=percent | 內(nèi)存占用達到-XX:MinHeapFreeRatio 的percent%時啟動CMS蒸播,默認值是80% |
其他 | |
-XX:MetaspaceSize | 設置觸發(fā)gc的元數(shù)據(jù)空間的大小 |
-Xlog:gc* | 發(fā)生垃圾收集時,打印日志萍肆,等同于PrintGCDetails
|
-Xlog:gc | 使用的是JVM Unified Logging Framework輸出log信息袍榆,等同于PrintGC , -Xlog 使用樣式:-Xlog:tag1[+tag2...][*][=level][:[output][:[decorators][:output-options [,...]]]]
|
-XX:MaxDirectMemorySize | java.nio包使用的內(nèi)存數(shù)量 |