真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java垃圾收集器的介紹以及JVM調優(yōu)方法

這篇文章主要講解了“Java垃圾收集器的介紹以及JVM調優(yōu)方法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java垃圾收集器的介紹以及JVM調優(yōu)方法”吧!

十余年的徽州網(wǎng)站建設經(jīng)驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。網(wǎng)絡營銷推廣的優(yōu)勢是能夠根據(jù)用戶設備顯示端的尺寸不同,自動調整徽州建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“徽州網(wǎng)站設計”,“徽州網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。

垃圾收集器

1.Serial

關注點:stw的時間 復制算法 STW

2.ParNew

關注點:stw的時間 Serial的多線程版本 復制算法 STW

參數(shù) -XX:ParallelGCThreads 并行線程數(shù)

3.Parallel Scavenge

關注點:達到一個可控制的吞吐量(吞吐量優(yōu)先) 復制算法 所謂吞吐量就是CPU運行用戶代碼的時間和CPU消耗的時間的比值,即吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間)。

Paralled Scavenge 收集器提供了兩個參數(shù)用于精確控制吞吐量。分別是控制最大垃圾收集停頓時間的-XX:MaxGCPauseMillis ,以及直接設置吞吐量大小的-XX:GCTimeRatio 參數(shù)。

參數(shù)

-XX:MaxGCPauseMillis 
-XX:GCTimeRatio
-XX:+UseAdaptiveSizePolicy 自適應調節(jié)策略

old區(qū)

1.Serial Old

Serial的老年代版本 
JDK1.5之前可搭配Parallel Scavenge使用
在CMS發(fā)生Concurrent mode failure時使用
Mark-Compact

2.Parallel Old

Parallel Scavenge的老年代版本
JDK1.6出現(xiàn) 搭配Parallel Scavenge使用
Mark-Compact

3.CMS

-XX:+UseConcMarkSweepGC
Mark-Sweep
過程:初始標記 并發(fā)標記 重新標記 并發(fā)清除
初始標記和重新標記會STW
耗時最長是并發(fā)標記和并發(fā)清除
默認回收線程數(shù):CMS默認啟動的回收線程數(shù)目是 (ParallelGCThreads + 3)/4),可以通過-XX:ParallelCMSThreads=20來設定

優(yōu)點:并發(fā)低停頓
缺點:
1、對CPU資源非常敏感 
占用部分線程(CPU資源)導致應用程序變慢,吞吐量降低
默認線程數(shù)=(CPU數(shù)量+3)/4
2、無法處理浮動垃圾,可能出現(xiàn)Concurrent mode failure而導致另一次fullGC的產(chǎn)生
參數(shù)-XX:CMSInitiatingOccupancyFraction默認68% CMS觸發(fā)百分比,CMS執(zhí)行期間,預留空間無法滿足,就會出現(xiàn)Concurrent mode failure失敗,啟動后備SerialOld的方案,停頓時間更長了。(所以CMSInitiatingOccupancyFraction不能設置的過大)
3、內存碎片
參數(shù)-XX:+UseCMSCompactAtFullCollection(停頓時間加長) 默認開啟
-XX:CMSFullGCsBeforeCompaction(執(zhí)行多少次不進行碎片整理的FullGC后進行一次帶壓縮的)

其他參數(shù)
初始標記的并行化-XX:+CMSParallelInitialMarkEnabled
為了減少第二次暫停的時間,開啟并行remark: -XX:+CMSParallelRemarkEnabled,如果remark還是過長的話,可以開啟-XX:+CMSScavengeBeforeRemark(在CMS GC前啟動一次ygc,目的在于減少old gen對ygc gen的引用,降低remark時的開銷-----一般CMS的GC耗時 80%都在remark階段)

為了避免Perm區(qū)滿引起的full gc,建議開啟CMS回收Perm區(qū)選項:
+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled

-XX:+UseConcMarkSweepGC:設置年老代為并發(fā)收集。測試中配置這個以后,-XX:NewRatio=4的配置失效了,原因不明。所以,此時年輕代大小最好用-Xmn設置。
-XX:+UseParNewGC:設置年輕代為并行收集??膳cCMS收集同時使用。JDK5.0以上,JVM會根據(jù)系統(tǒng)配置自行設置,所以無需再設置此值。

G1收集器

收集器組合開關選項

-XX:+UseSerialGC Serial+SerialOld
-XX:+UseParNewGC ParNew+SerialOld
-XX:+UseParallelGC ParallelScavenge+SerialOld 
-XX:+UseConcMarkSweepGC ParNew+CMS+SerialOld  FullGC算法:單線程的Mark Sweep Compact(MSC)
-XX:+UseParallelOldGC ParallelScavenge+Parallel Old  FullGC算法:PS MarkSweep

JVM參數(shù)

垃圾回收參數(shù)
-Xnoclassgc 是否對類進行回收
-verbose:class -XX:+TraceClassUnloading 查看類加載和卸載信息

-XX:SurvivorRatio Eden和其中一個survivor的比值
-XX:PretenureSizeThreshold 大對象進入老年代的閾值,Serial和ParNew生效
-XX:MaxTenuringThreshold 晉升老年代的對象年齡,默認15, CMS默認是4
-XX:HandlePromotionFailure 老年代擔保
-XX:+UseAdaptiveSizePolicy動態(tài)調整Java堆中各個區(qū)域大小和進入老年代年齡
-XX:ParallelGCThreads 并行回收的線程數(shù)
-XX:MaxGCPauseMillis Parallel Scavenge參數(shù),設置GC的最大停頓時間
-XX:GCTimeRatio  Parallel Scavenge參數(shù),GC時間占總時間的比率,默認99%,即1%的GC時間
-XX:CMSInitiatingOccupancyFraction,old區(qū)觸發(fā)cms閾值,默認68%
-XX:+UseCMSCompactAtFullCollection(CMS完成后是否進行一次碎片整理,停頓時間加長)
-XX:CMSFullGCsBeforeCompaction(執(zhí)行多少次不進行碎片整理的FullGC后進行一次帶壓縮的)
-XX:+ScavengeBeforeFullGC,在fullgc前觸發(fā)一次minorGC

垃圾回收統(tǒng)計信息
-XX:+PrintGC 輸出GC日志
-verbose:gc等同于上面那個
-XX:+PrintGCDetails 輸出GC的詳細日志

堆大小設置
-Xmx:最大堆大小
-Xms:初始堆大小(最小內存值)
-Xmn:年輕代大小
-XX:NewSize和-XX:MaxNewSize 新生代大小
-XX:SurvivorRatio:3 意思是年輕代中Eden區(qū)與兩個Survivor區(qū)的比值。注意Survivor區(qū)有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區(qū)占整個年輕代的1/5
-XX:NewRatio=4:設置年輕代(包括Eden和兩個Survivor區(qū))與年老代的比值(除去持久代)。設置為4,則年輕代與年老代所占比值為1:4,年輕代占整個堆棧的1/5
-Xss棧容量 默認256k
-XX:PermSize永久代初始值
-XX:MaxPermSize 永久代最大值

生產(chǎn)環(huán)境參數(shù)配置(CMS-GC)

Java < 8
    -server
    -Xms[g|m|k] -Xmx[g|m|k]
    -XX:PermSize=[g|m|k] -XX:MaxPermSize=[g|m|k]
    -Xmn[g|m|k]
    -XX:+DisableExplicitGC
    -XX:SurvivorRatio=
    -XX:+UseConcMarkSweepGC 
    -XX:+CMSParallelRemarkEnabled
    -XX:+CMSScavengeBeforeRemark
    -XX:+UseCMSInitiatingOccupancyOnly 
    -XX:CMSInitiatingOccupancyFraction=
    -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:""
    -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=`date`.hprof
    -Dsun.net.inetaddr.ttl=
    -Djava.rmi.server.hostname=
    -Dcom.sun.management.jmxremote.port= 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false

Java >= 8
    -server
    -Xms[g|m|k] -Xmx[g|m|k]
    -XX:MaxMetaspaceSize=[g|m|k]
    -Xmn[g|m|k]
    -XX:+DisableExplicitGC
    -XX:SurvivorRatio=
    -XX:+UseConcMarkSweepGC 
    -XX:+CMSParallelRemarkEnabled
    -XX:+CMSScavengeBeforeRemark
    -XX:+UseCMSInitiatingOccupancyOnly
    -XX:CMSInitiatingOccupancyFraction=
    -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:""
    -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=`date`.hprof
    -Dsun.net.inetaddr.ttl=
    -Djava.rmi.server.hostname=
    -Dcom.sun.management.jmxremote.port= 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false

理解GC日志

DefNew:Serial收集器新生代名稱 - Tenured - Perm
ParNew:ParNew收集器新生代名稱 - 
PSYoungGen:Parallel Scavenge收集器新生代名稱

JVM調優(yōu)

  • GC的時間足夠的小

  • GC的次數(shù)足夠的少

  • 發(fā)生Full GC的周期足夠的長

前兩個目前是相悖的,要想GC時間小必須要一個更小的堆,要保證GC次數(shù)足夠少,必須保證一個更大的堆,我們只能取其平衡。

(1)針對JVM堆的設置,一般可以通過-Xms -Xmx限定其最小、最大值,為了防止垃圾收集器在最小、最大之間收縮堆而產(chǎn)生額外的時間,我們通常把最大、最小設置為相同的值

(2)年輕代和年老代將根據(jù)默認的比例(1:2)分配堆內存,可以通過調整二者之間的比率NewRadio來調整二者之間的大小,也可以針對回收代,比如年輕代,通過 -XX:newSize -XX:MaxNewSize來設置其絕對大小。同樣,為了防止年輕代的堆收縮,我們通常會把-XX:newSize -XX:MaxNewSize設置為同樣大小。-XX:PermSize,-XX:MaxPermSize設置為一樣防止老年代收縮。 -XX:NewRatio=4:設置年輕代(包括Eden和兩個Survivor區(qū))與年老代的比值(除去持久代)。設置為4,則年輕代與年老代所占比值為1:4,年輕代占整個堆棧的1/5 -XX:MaxTenuringThreshold=0:設置垃圾最大年齡。如果設置為0的話,則年輕代對象不經(jīng)過Survivor區(qū),直接進入年老代。對于年老代比較多的應用,可以提高效率。如果將此值設置為一個較大值,則年輕代對象會在Survivor區(qū)進行多次復制,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概論。

(3)年輕代和年老代設置多大才算合理?這個我問題毫無疑問是沒有答案的,否則也就不會有調優(yōu)。我們觀察一下二者大小變化有哪些影響 年輕代老年代設置:整個JVM內存大小=年輕代大小 + 年老代大小 + 持久代大小。持久代一般固定大小為64m,所以增大年輕代后,將會減小年老代大小。此值對系統(tǒng)性能影響較大,Sun官方推薦年輕代配置為整個堆的3/8。

  • 更大的年輕代必然導致更小的年老代,大的年輕代會延長普通GC的周期,但會增加每次GC的時間;小的年老代會導致更頻繁的Full GC

  • 更小的年輕代必然導致更大年老代,小的年輕代會導致普通GC很頻繁,但每次的GC時間會更短;大的年老代會減少Full GC的頻率

  • 如何選擇應該依賴應用程序對象生命周期的分布情況:如果應用存在大量的臨時對象,應該選擇更大的年輕代;如果存在相對較多的持久對象,年老代應該適當增大。但很多應用都沒有這樣明顯的特性,在抉擇時應該根據(jù)以下兩點:(A)本著Full GC盡量少的原則,讓年老代盡量緩存常用對象,JVM的默認比例1:2也是這個道理 (B)通過觀察應用一段時間,看其他在峰值時年老代會占多少內存,在不影響Full GC的前提下,根據(jù)實際情況加大年輕代,比如可以把比例控制在1:1。但應該給年老代至少預留1/3的增長空間

(4)在配置較好的機器上(比如多核、大內存),可以為年老代選擇并行收集算法: -XX:+UseParallelOldGC ,默認為Serial收集

(5)線程堆棧的設置:每個線程默認會開啟1M的堆棧,用于存放棧幀、調用參數(shù)、局部變量等,對大多數(shù)應用而言這個默認值太了,一般256K就足用。理論上,在內存不變的情況下,減少每個線程的堆棧,可以產(chǎn)生更多的線程,但這實際上還受限于操作系統(tǒng)。 -Xss256k:設置每個線程的堆棧大小。JDK5.0以后每個線程堆棧大小為1M,以前每個線程堆棧大小為256K。更具應用的線程所需內存大小進行調整。在相同物理內存下,減小這個值能生成更多的線程。但是操作系統(tǒng)對一個進程內的線程數(shù)還是有限制的,不能無限生成,經(jīng)驗值在3000~5000左右。

(6)可以通過下面的參數(shù)打Heap Dump信息

  -XX:HeapDumpPath
  -XX:+PrintGCDetails
  -XX:+PrintGCTimeStamps
  -Xloggc:/usr/aaa/dump/heap_trace.txt
  通過下面參數(shù)可以控制OutOfMemoryError時打印堆的信息
  -XX:+HeapDumpOnOutOfMemoryError

注:通過分析dump文件可以發(fā)現(xiàn),每個1小時都會發(fā)生一次Full GC,經(jīng)過多方求證,只要在JVM中開啟了JMX服務,JMX將會1小時執(zhí)行一次Full GC以清除引用.

性能分析工具

jps

-m 主類的參數(shù) 
-l 主類的全名,如果執(zhí)行的是jar包,輸出jar路徑
-v 虛擬機參數(shù)

jstat

監(jiān)視虛擬機運行狀態(tài)信息,包括類裝載、GC、運行期編譯(JIT)
用于輸出java程序內存使用情況,包括新生代、老年代、元數(shù)據(jù)區(qū)容量、垃圾回收情況
 jstat -gcutil 52670 2000 5 進程號 2s輸出一次一共5次

S0:幸存1區(qū)當前使用比例
S1:幸存2區(qū)當前使用比例
E:伊甸園區(qū)使用比例
O:老年代使用比例
M:元數(shù)據(jù)區(qū)使用比例
CCS:壓縮使用比例
YGC:年輕代垃圾回收次數(shù)
YGCT:年輕代垃圾回收消耗時間
FGC:老年代垃圾回收次數(shù)
FGCT:老年代垃圾回收消耗時間
GCT:垃圾回收消耗總時間

jmap

jmap:用于生成堆轉儲快照。一般稱為dump或heapdump文件。
jmap -histo 3618
上述命令打印出進程ID為3618的內存情況,包括有哪些對象,對象的數(shù)量。但我們常用的方式是將指定進程的內存heap輸出到外              部文件,再由專門的heap分析工具進行分析,例如mat(Memory Analysis Tool),所以我們常用的命令是:
jmap -dump:live,format=b,file=heap.hprof 3618
-F 強制生成dump快照

jstack

jstack:用戶輸出虛擬機當前時刻的線程快照,常用于定位因為某些線程問題造成的故障或性能問題。一般稱為threaddump文件。
參數(shù)
-F當正常輸出沒有響應的時候強制打印棧信息,一般情況不需要使用
-l長列表. 打印關于鎖的附加信息,一般情況不需要使用
-m 如果調用本地方法的話,可打印c/c++的堆棧

jinfo

查看和修改虛擬機參數(shù)

可視化工具 JConsole Java監(jiān)視與管理控制臺 VisualVM 多合一故障處理工具

Java Class文件類型前綴

Element Type        Encoding
boolean             Z
byte                B
char                C
double              D
float               F
int                 I
long                J
short               S 
class or interface  Lclassname;
[L代表了相應類型數(shù)組嵌套的層數(shù)

內存泄漏及解決方法

1.系統(tǒng)崩潰前的一些現(xiàn)象:

每次垃圾回收的時間越來越長,由之前的10ms延長到50ms左右,F(xiàn)ullGC的時間也有之前的0.5s延長到4、5s

FullGC的次數(shù)越來越多,最頻繁時隔不到1分鐘就進行一次FullGC

年老代的內存越來越大并且每次FullGC后年老代沒有內存被釋放

之后系統(tǒng)會無法響應新的請求,逐漸到達OutOfMemoryError的臨界值。

2.生成堆的dump文件 通過JMX的MBean生成當前的Heap信息,大小為一個3G(整個堆的大?。┑膆prof文件,如果沒有啟動JMX可以通過Java的jmap命令來生成該文件。

3.分析dump文件

下面要考慮的是如何打開這個3G的堆信息文件,顯然一般的Window系統(tǒng)沒有這么大的內存,必須借助高配置的Linux。當然我們可以借助X-Window把Linux上的圖形導入到Window。我們考慮用下面幾種工具打開該文件:

1.Visual VM 2.IBM HeapAnalyzer 3.JDK 自帶的Hprof工具

使用這些工具時為了確保加載速度,建議設置最大內存為6G。使用后發(fā)現(xiàn),這些工具都無法直觀地觀察到內存泄漏,Visual VM雖能觀察到對象大小,但看不到調用堆棧;HeapAnalyzer雖然能看到調用堆棧,卻無法正確打開一個3G的文件。因此,我們又選用了Eclipse專門的靜態(tài)內存分析工具:Mat。

4.分析內存泄漏

通過Mat我們能清楚地看到,哪些對象被懷疑為內存泄漏,哪些對象占的空間最大及對象的調用關系。針對本案,在ThreadLocal中有很多的JbpmContext實例,經(jīng)過調查是JBPM的Context沒有關閉所致。

另,通過Mat或JMX我們還可以分析線程狀態(tài),可以觀察到線程被阻塞在哪個對象上,從而判斷系統(tǒng)的瓶頸。

5.回歸問題

Q:為什么崩潰前垃圾回收的時間越來越長?

A:根據(jù)內存模型和垃圾回收算法,垃圾回收分兩部分:內存標記、清除(復制),標記部分只要內存大小固定,時間是不變的,變的是復制部分,因為每次垃圾回收都有一些回收不掉的內存,所以增加了復制量,導致時間延長。所以,垃圾回收的時間也可以作為判斷內存泄漏的依據(jù)

Q:為什么Full GC的次數(shù)越來越多?

A:因此內存的積累,逐漸耗盡了年老代的內存,導致新對象分配沒有更多的空間,從而導致頻繁的垃圾回收

Q:為什么年老代占用的內存越來越大?

A:因為年輕代的內存無法被回收,越來越多地被Copy到年老代

調優(yōu)方法

一切都是為了這一步,調優(yōu),在調優(yōu)之前,我們需要記住下面的原則:

1、多數(shù)的Java應用不需要在服務器上進行GC優(yōu)化;

2、多數(shù)導致GC問題的Java應用,都不是因為我們參數(shù)設置錯誤,而是代碼問題;

3、在應用上線之前,先考慮將機器的JVM參數(shù)設置到最優(yōu)(最適合)

4、減少創(chuàng)建對象的數(shù)量;

5、減少使用全局變量和大對象;

6、GC優(yōu)化是到最后不得已才采用的手段;

7、在實際使用中,分析GC情況優(yōu)化代碼比優(yōu)化GC參數(shù)要多得多;

GC優(yōu)化的目的有兩個

1、將轉移到老年代的對象數(shù)量降低到最?。?/p>

2、減少full GC的執(zhí)行時間;

為了達到上面的目的,一般地,你需要做的事情有:

1、減少使用全局變量和大對象;

2、調整新生代的大小到最合適;

3、設置老年代的大小為最合適;

4、選擇合適的GC收集器

感謝各位的閱讀,以上就是“Java垃圾收集器的介紹以及JVM調優(yōu)方法”的內容了,經(jīng)過本文的學習后,相信大家對Java垃圾收集器的介紹以及JVM調優(yōu)方法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關知識點的文章,歡迎關注!


新聞名稱:Java垃圾收集器的介紹以及JVM調優(yōu)方法
文章來源:http://weahome.cn/article/gocpjj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部