日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java虚拟机:常见JVM参数配置和GC性能优化

發布時間:2024/9/30 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java虚拟机:常见JVM参数配置和GC性能优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、常見的JVM參數配置:

1、垃圾回收統計信息

-XX:+PrintGC?????打印GC簡要信息

-XX:+PrintGCDetails打印GC的詳細信息

-XX:+PrintGCTimeStamps打印CG發生的時間戳

-Xloggc:log/gc.log?指定GC log的位置,以文件輸出

-XX:+PrintHeapAtGC?每一次GC前和GC后,都打印堆信息。

2、堆設置

-Xms:初始堆大,最小堆

-Xmx:最大堆大小

-Xmn:設置新生代的大小

-XX:NewRatio新生代和年老代的比值,如為3,表示年輕代與年老代比值為1:3,年輕代占整個年輕代年老代之和的1/4

-XX:SurvivorRatio設置兩個Survivor區和eden的比值。注意Survivor區有兩個。如:8,表示Eden:Survivor=8:2,一個Survivor區占整個年輕代的1/10

-XX:PermSize:設置永久區的初始空間

-XX:MaxPermSize:設置永久區的最大空間。

-XX:+MaxTenuringThreshold=10:新生代垃圾的最大年齡,代表對象在Survivor區經過10次復制以后才進入老年代。如果設置為0,則年輕代對象不經過Survivor區,直接進入老年代。

-XX:+PretenureSizeThreshold:設置大對象直接進入老年代的閾值。當對象的大小超過這個值時,將直接在老年代分配。?

3、棧的分配參數:

-Xss:設置棧空間的大小。

4、垃圾收集器設置

(1)串行收集器的設置:

-XX:+UseSerialGC:設置串行收集器,一般適用于小型應用和單處理器,算法比較簡單,GC效率也較高,但可能會給應用帶來停頓。

(2)并行回收收集器設置(ParallelGC收集器的目標是達到一個可控制的吞吐量)

-XX:+UseParNewGC:設置年輕代為并行收集。

-XX:+UseParallelGC:設置年輕代使用并行回收收集器。多個線程并行執行GC,一般適用于多處理器系統中,可以提高GC的效率,但算法復雜,系統消耗較大。

-XX:+UseParalledlOldGC:設置老年代為并行回收收集器,Java1.6之后才出現。

-XX:ParallelGCThreads=n:設置并行收集器收集時使用的線程數,最好與CPU數目相等。

-XX:MaxGCPauseMillis=n:設置年輕代每次并行垃圾回收的最大暫停時間。

-XX:GCTimeRatio=n:設置垃圾回收時間占程序運行時間的百分比。公式為1/(1+n)

-XX:+UseAdaptiveSizePolicy:自適應策略,自動選擇年輕代區大小和相應的Survivor區比例。

(3)CMS并發收集器:(以最短停頓為目標)

-XX:+UseConcMarkSweepGC:使用CMS內存收集。

-XX:+ParallelCMSThreads: 設定 CMS 的線程數量。?

-XX:CMSFullGCsBeforeCompaction:CMS多少次后進行內存壓縮,由于并發收集器不對內存空間進行壓縮整理,所以運行一段時間以后會產生"碎片",使得運行效率降低。

-XX:+UseCMSCompactAtFullCollection:在FULL GC的時候,對年老代的壓縮。CMS是不會移動內存的,因此,這個非常容易產生碎片,導致內存不夠用,因此,內存的壓縮這個時候就會被啟用。可能會影響性能,但是可以消除碎片。

-XX:+CMSInitiatingOccupancyFraction:設置 CMS 收集器在老年代空間被使用多少后觸發,默認為 68%。?

-XX:+CMSClassUnloadingEnabled:允許對類元數據進行回收。

-XX:+CMSParallelRemarkEndable:啟用并行重標記。?

-XX:CMSInitatingPermOccupancyFraction:當永久區占用率達到這一百分比后,啟動 CMS 回收 (前提是-XX:+CMSClassUnloadingEnabled 激活了)。?

-XX:UseCMSInitatingOccupancyOnly:表示只在到達閾值的時候,才進行 CMS 回收。?

-XX:+CMSIncrementalMode:使用增量模式,比較適合單 CPU。?

(4)G1收集器:

-XX:+UseG1GC:使用 G1 回收器。?

-XX:+UnlockExperimentalVMOptions:允許使用實驗性參數。?

-XX:+MaxGCPauseMills:設置最大垃圾收集停頓時間。?

-XX:+GCPauseIntervalMills:設置停頓間隔時間。?

更多參數的詳細介紹和設置可以參考這篇博客:https://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html

二、JVM的GC性能優化:

對于GC的性能主要有2個方面的指標:吞吐量(工作時間不算,gc的時間占總的時間比)和暫停時間。

1. 堆大小:

?????? 默認情況下,vm會增加/減少heap大小以維持free space在整個vm中占的比例,這個比例由MinHeapFreeRatio和MaxHeapFreeRatio指定。

一般而言,server端的app會有以下規則:

(1)對vm分配盡可能多的內存;

(2)將Xms和Xmx設為一樣的值。如果虛擬機啟動時設置使用的內存比較小,這個時候又需要初始化很多對象,虛擬機就必須重復地增加內存。

(3)處理器核數增加,內存也跟著增大。

2. 年輕代:

?????? (1)對于程序流暢性運行影響的因素是新生代的大小。新生代越大,minor collection越少;但是在堆大小固定情況下,新生代越大就意味著越小的老年代,就意味著更多的major collection。

?????? (2)NewRatio反映的是新生代和老年代的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限,將這兩個值設為一樣就固定了young generation的大小(同Xms和Xmx設為一樣)。

??????(3)SurvivorRatio也可以優化survivor的大小,不過這對于性能的影響不是很大。SurvivorRatio是Eden和Survior大小比例。

一般而言,server端的app會有以下規則:

(1)首先決定能分配給vm的最大的堆大小,然后設定最佳的young generation的大小;

(2)如果堆大小固定后,增加新生代的大小意味著減小老年代大小。讓老年代在任何時候夠大,能夠容納所有存活的對象(留10%-20%的空余)。

3、年輕代大小選擇

(1)響應時間優先的應用:盡可能設大,直到接近系統的最低響應時間限制,在此種情況下,年輕代收集發生的頻率也是最小的,同時,減少到達年老代的對象。

(2)吞吐量優先的應用:盡可能的設置大,可能到達Gbit的程度,因為對響應時間沒有要求,垃圾收集可以并行進行,一般適合8CPU以上的應用。

(3)避免設置過小。當新生代設置過小時會導致:①YGC次數更加頻繁;②可能導致YGC對象直接進入舊生代,如果此時舊生代滿了,會觸發FGC。

4、年老代大小選擇

(1)響應時間優先的應用:年老代使用并發收集器。如果堆設置小了,可以會造成內存碎片、高回收頻率以及應用暫停而使用傳統的標記清除方式;如果堆大了,則需要較長的收集時間。一般需要參考以下數據:

并發垃圾收集信息、持久代并發收集次數、傳統GC信息、花在年輕代和年老代回收上的時間比例。

(2)吞吐量優先的應用:一般吞吐量優先的應用都有一個很大的年輕代和一個較小的年老代,這樣可以盡可能回收掉大部分短期對象,減少中期的對象,而年老代盡存放長期存活對象。

5、較小堆引起的碎片問題
因為CMS年老代的并發收集器使用標記清除算法所以不會對堆進行壓縮當收集器回收時,他會把相鄰的空間進行合并,這樣可以分配給較大的對象。但是,當堆空間較小時,運行一段時間以后,就會出現"碎片",如果并發收集器找不到足夠的空間,那么并發收集器將會停止,可能需要進行如下配置:
-XX:+UseCMSCompactAtFullCollection:使用并發收集器時,開啟對年老代的壓縮。
-XX:CMSFullGCsBeforeCompaction=0:上面配置開啟的情況下,這里設置多少次Full GC后,對年老代進行壓縮。

4、用64位操作系統,Linux下64位的jdk比32位jdk要慢一些,但是吃得內存更多,吞吐量更大。

5、XMX和XMS設置一樣大,MaxPermSize和MinPermSize設置一樣大,這樣可以減輕伸縮堆大小帶來的壓力

6、CMS的目標是最短的GC停頓時間,使用CMS的好處是用盡量少的新生代,然后老生代利用CMS并行收集,這樣能保證系統低延遲的吞吐效率。

7、系統停頓的時候可能是GC的問題也可能是程序的問題,多用jmap和jstack查看,或者killall -3 java,然后查看java控制臺日志,能看出很多問題。

8、如果用了緩存,那么年老代應該大一些,緩存的HashMap不應該無限制長,建議采用LRU算法的Map做緩存,LRUMap的最大長度也要根據實際情況設定。

9、采用并發回收時,年輕代小一點,年老代要大,因為年老代用的是并發回收,即使時間長點也不會影響其他程序繼續運行,網站不會停頓。

10、JVM參數的設置(特別是 –Xmx –Xms –Xmn -XX:SurvivorRatio? -XX:MaxTenuringThreshold等參數的設置)沒有一個固定的公式,需要根據PV old區實際數據、YGC次數等多方面來衡量。為了避免promotion faild可能會導致xmn設置偏小,也意味著YGC的次數會增多,處理并發訪問的能力下降等問題。每個參數的調整都需要經過詳細的性能測試,才能找到特定應用的最佳配置。

promotion failed:(晉升失敗)

垃圾回收時promotion failed,一般可能是兩種原因產生,第一個原因是To survivor救助空間不夠,救助空間里的對象還不應該被移動到年老代,但年輕代又有很多對象需要放入救助空間;第二個原因是年老代沒有足夠的空間接納來自年輕代的對象;這兩種情況都會轉向Full GC,網站停頓時間較長。

解決方案:

第一個原因解決辦法是去掉救助空間,設置-XX:SurvivorRatio=65536?-XX:MaxTenuringThreshold=0即可,但是因為沒有用到救助空間,所以年老代容易滿,Full GC執行會比較頻繁,所以可以把救助空間加大,這樣也不會有promotion failed。

第二個原因我的解決辦法是設置CMSInitiatingOccupancyFraction為某個值(假設70),這樣年老代空間到70%時就開始執行CMS,年老代有足夠的空間接納來自年輕代的對象。

11、實際編程中的性能優化:

下面是一些在實際寫程序的過程中應該注意的點:養成這些習慣可以在一定程度上減少內存的無謂消耗,進一步就可以減少因為內存不足導致GC不斷。參考自:https://blog.csdn.net/antony9118/article/details/51375662

(1)減少new對象。每次new對象之后,都要開辟新的內存空間。這些對象不被引用之后,還要回收掉。因此,如果最大限度地合理重用對象,或者使用基本數據類型替代對象,都有助于節省內存;

(2)多使用局部變量,減少使用靜態變量。局部變量被創建在棧中,存取速度快。靜態變量則是在堆內存;

(3)避免使用finalize,該方法會給GC增添很大的負擔;

(4)如果是單線程,盡量使用非多線程安全的,因為線程安全來自于同步機制,同步機制會降低性能。例如,單線程程序,能使用HashMap,就不要用HashTable。同理,盡量減少使用synchronized

(5)用移位符號替代乘除號。eg:a*8應該寫作a<<3

(6)對于經常反復使用的對象使用緩存;

(7)盡量使用基本類型而不是包裝類型,盡量使用一維數組而不是二維數組;

(8)盡量使用final修飾符,final表示不可修改,訪問效率高;

(9)單線程情況下(或者是針對于局部變量),字符串盡量使用StringBuilder,比StringBuffer要快;

(10)String為什么慢?因為String 是不可變的對象, 因此在每次對 String 類型進行改變的時候其實都等同于生成了一個新的 String 對象,然后將指針指向新的 String 對象。如果不能保證線程安全,盡量使用StringBuffer來連接字符串。這里需要注意的是,StringBuffer的默認緩存容量是16個字符,如果超過16,apend方法調用私有的expandCapacity()方法,來保證足夠的緩存容量。因此,如果可以預設StringBuffer的容量,避免append再去擴展容量。如果可以保證線程安全,就是用StringBuilder。
?

總結

以上是生活随笔為你收集整理的Java虚拟机:常见JVM参数配置和GC性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。