JVM的OOM分為多種狀況,下面會(huì)針對(duì)java.lang.OutOfMemoryError:Javaheapspace這種狀況解說(shuō)一下產(chǎn)生的原因與解決方案。
在JAVA運(yùn)用啟動(dòng)時(shí),會(huì)限制運(yùn)用的運(yùn)用空間。也就說(shuō),任何一個(gè)JAVA運(yùn)用,都只能運(yùn)用有限的內(nèi)存空間。
JAVA的內(nèi)存空間在JDK7及曾經(jīng)劃分為堆與永久代。在JDK8之后移除了永久代,選用元空間來(lái)代替。
在啟動(dòng)時(shí),經(jīng)過(guò)指定JVM參數(shù):`-Xmx`來(lái)設(shè)置可運(yùn)用的最大堆巨細(xì)。假如沒(méi)有顯式的設(shè)置,則系統(tǒng)上默以為物理內(nèi)存的1/4(依據(jù)物理內(nèi)存的不同狀況有不同的分配規(guī)則。可是遍及能夠以為是1/4)。
產(chǎn)生java.lang.OutOfMemoryError:Javaheapspace反常時(shí),代表著運(yùn)用嘗試從堆上申請(qǐng)一個(gè)區(qū)域時(shí),堆沒(méi)有可配的空間。(注:可能有可運(yùn)用的物理內(nèi)存,可是沒(méi)有現(xiàn)已達(dá)到了JAVA運(yùn)用可分配的內(nèi)存巨細(xì))
JVM是很智能的,在即將產(chǎn)生OOM時(shí),會(huì)進(jìn)行一次FullGC以收回可收回的目標(biāo)來(lái)釋放空間。假如FullGC之后仍是沒(méi)有可滿意巨細(xì)的空間分配,才拋出java.lang.OutOfMemoryError:Javaheapspace。
java.lang.OutOfMemoryError:Javaheapspace正常是怎么產(chǎn)生的呢?
突發(fā)高峰期:程序在正常的用戶量和必定數(shù)據(jù)量時(shí)運(yùn)轉(zhuǎn)正常??墒牵谀硞€(gè)高峰時(shí)導(dǎo)致超出預(yù)期閾值,內(nèi)存存活目標(biāo)運(yùn)用空間的量超出最大堆,并且無(wú)法收回。內(nèi)存走漏:因?yàn)榫幊体e(cuò)誤導(dǎo)致運(yùn)用程序不再需求的目標(biāo)(數(shù)據(jù))一向被持有引證,導(dǎo)致無(wú)法被收回。隨著時(shí)刻的推移,走漏的內(nèi)存目標(biāo)占用了一切的可用堆空間。分配合理的滿意內(nèi)存
最簡(jiǎn)略的解決方法就給JVM分配滿意大的內(nèi)存來(lái)滿意運(yùn)轉(zhuǎn)程序的需求。
可是,需求留意在內(nèi)存走漏的狀況下,分配再大的內(nèi)存也只是推遲了java.lang.OutOfMemoryError:Javaheapspace的產(chǎn)生。
并且,加大了JVM堆內(nèi)存,也會(huì)增加在GC時(shí)的暫停時(shí)刻(STW),影響程序的吞吐量,增加推遲。
怎么分配一個(gè)合理的內(nèi)存空間,是需求針對(duì)GC進(jìn)行優(yōu)化的。也就是常說(shuō)的JVM調(diào)優(yōu)。JVM調(diào)優(yōu)能夠參考:「JVM」GC——調(diào)優(yōu)介紹
那么,怎么調(diào)整經(jīng)過(guò)分配JAVA堆空間來(lái)解決問(wèn)題呢?
首先,需求了解以下這些問(wèn)題:
哪些目標(biāo)占用了很多的堆空間在哪些代碼中創(chuàng)建了這些目標(biāo)上述的問(wèn)題能夠經(jīng)過(guò)JVM自身的jmap來(lái)dump出運(yùn)轉(zhuǎn)時(shí)的堆棧信息。然后經(jīng)過(guò)如:MAT,JProfiler,jconsole等空間來(lái)進(jìn)行內(nèi)存目標(biāo)占用的盯梢。
MAT運(yùn)用能夠參考:[JVM]MAT進(jìn)階運(yùn)用
當(dāng)然,這種方式是比較原始的方式。主張經(jīng)過(guò)如:Plumbr等JVM監(jiān)控東西來(lái)盯梢問(wèn)題。
Plumbr的陳述信息
以上圖的監(jiān)控舉例扼要闡明一下怎么適當(dāng)?shù)倪M(jìn)行堆空間的巨細(xì)分配。
上圖所示中,能夠得到如下信息:
一切相關(guān)目標(biāo)的整個(gè)GCRoot引證內(nèi)存消耗最多的目標(biāo):
這些目標(biāo)在代碼中的分配方位:
依據(jù)上述的信息,我們能夠得到這樣的猜測(cè):
這個(gè)程序的需求的運(yùn)轉(zhuǎn)空間超過(guò)248MB,并且是無(wú)法在必定時(shí)刻內(nèi)釋放被收回。那么,按JVM調(diào)優(yōu)的思路,主張分配的最大堆巨細(xì)為:老年代活躍數(shù)據(jù)巨細(xì)*3~4倍。
所以,我們第一次調(diào)整時(shí),能夠分配:248*4=992。
因?yàn)槎丫藜?xì)的無(wú)法確認(rèn),所以第一次調(diào)整直接調(diào)整為:-Xmx1024m。
單位:-Xmx1024即裝備1024b=1kb-Xmx1024k即裝備1mb-Xmx1024m即裝備1gb-Xmx1g即裝備1gb主張:在裝備-Xmx時(shí),應(yīng)該將-Xms也裝備成相同巨細(xì)。避免JVM需求動(dòng)態(tài)調(diào)整堆空間巨細(xì)帶來(lái)的功能影響。
在JVM中假如98%的時(shí)刻是用于GC(GarbageCollection)且可用的Heapsize不足2%的時(shí)分將拋出反常信息,java.lang.OutOfMemoryError:Javaheapspace。
所以產(chǎn)生這個(gè)異樣的原因一般有兩種:
1.程序中出現(xiàn)了死循環(huán)
2.程序占用內(nèi)存太多,超越了JVM堆設(shè)置的最大值。
關(guān)于第一種狀況,需求自己檢查程序代碼,這里不再多說(shuō)。
第二種狀況,我們手藝擴(kuò)展JVM堆的參數(shù)設(shè)置。JVM堆的設(shè)置是指java程序運(yùn)轉(zhuǎn)過(guò)程中JVM能夠分配運(yùn)用的內(nèi)存空間的設(shè)置。在JVM發(fā)動(dòng)時(shí),JVM堆會(huì)主動(dòng)設(shè)置heapsize值。一般狀況下,初始空間(即-Xms)默認(rèn)值是物理內(nèi)存的1/64,最大空間是物理內(nèi)存的1/4。能夠運(yùn)用JVM供給的-Xmn-Xms-Xmx等選項(xiàng)可進(jìn)行設(shè)置。這里對(duì)各個(gè)參數(shù)的含義解釋一下:-Xms:初始值-Xmx:最大值-Xmn:最小值HeapSize的設(shè)置不宜太小,也不宜太大。若設(shè)置太小程序的響應(yīng)速度會(huì)變慢了,由于GC占用了更多的時(shí)刻,而運(yùn)用分配到的履行時(shí)刻較少。太大也會(huì)形成空間的糟蹋,并且也會(huì)影響其他程序的正常運(yùn)轉(zhuǎn)。HeapSize最大最好不要超越可用物理內(nèi)存的80%。建議將-Xms和-Xmx選項(xiàng)設(shè)置為相同,而-Xmn為1/4的-Xmx值。設(shè)置的辦法首要有以下幾個(gè):
1.便是在履行JAVA類文件時(shí)加上這個(gè)參數(shù),其間className是需求履行確實(shí)類名。(包含包名)如:java-Xms32m-Xmx800mclassName這個(gè)不只解決問(wèn)題了,并且履行的速度比沒(méi)有設(shè)置的時(shí)分快許多。假如是開發(fā)測(cè)驗(yàn),也能夠再eclipse中直接設(shè)置。Eclipse->run-arguments中的VMarguments中輸入-Xms32m-Xmx800m這個(gè)參數(shù)就能夠了。
2.能夠在windows更改體系環(huán)境變量加上JAVA_OPTS=-Xms64m-Xmx512m。3.假如用的tomcat,在windows下,能夠在C:\tomcat5.5.9\bin\catalina.bat(詳細(xì)途徑依據(jù)自己tomcat的位置而定)中加上:setJAVA_OPTS=-Xms64m-Xmx256m(巨細(xì)依自己內(nèi)存而定)位置在:remGuessCATALINA_HOMEifnotdefined這行的下面加合適.4.假如是linux體系Linux在{tomcat_home}/bin/catalina.sh的前面,加setJAVA_OPTS=’-Xms64-Xmx512′
由于程序要從數(shù)據(jù)讀取近10W行記載處理,當(dāng)讀到9W的時(shí)分就出現(xiàn)java.lang.OutOfMemoryError:Javaheapspace這樣的過(guò)錯(cuò)。
在網(wǎng)上一查或許是JAVA的倉(cāng)庫(kù)設(shè)置太小的原因。
跟據(jù)網(wǎng)上的答案大致有這兩種解決辦法:
1、設(shè)置環(huán)境變量
setJAVA_OPTS=-Xms32m-Xmx512m
能夠依據(jù)自己機(jī)器的內(nèi)存進(jìn)行更改,但自己測(cè)驗(yàn)這種辦法并沒(méi)有解決問(wèn)題?;蛟S是還有哪里需求設(shè)置。
2、java-Xms32m-Xmx800mclassName
便是在履行JAVA類文件時(shí)加上這個(gè)參數(shù),其間className是需求履行確實(shí)類名。(包含包名)
這個(gè)解決問(wèn)題了。并且履行的速度比沒(méi)有設(shè)置的時(shí)分快許多。
假如在測(cè)驗(yàn)的時(shí)分或許會(huì)用Eclispe這時(shí)分就需求在Eclipse->run-arguments中的VMarguments中輸入-Xms32m-Xmx800m這個(gè)參數(shù)就能夠了。
java.lang.OutOfMemoryError:Javaheapspace
===================================================
運(yùn)用Java程序從數(shù)據(jù)庫(kù)中查詢大量的數(shù)據(jù)時(shí)出現(xiàn)反常:
java.lang.OutOfMemoryError:Javaheapspace
在JVM中假如98%的時(shí)刻是用于GC且可用的Heapsize不足2%的時(shí)分將拋出此反常信息。
JVM堆的設(shè)置是指java程序運(yùn)轉(zhuǎn)過(guò)程中JVM能夠分配運(yùn)用的內(nèi)存空間的設(shè)置.
JVM在發(fā)動(dòng)的時(shí)分會(huì)主動(dòng)設(shè)置Heapsize的值,其初始空間(即-Xms)是物理內(nèi)存的1/64,最大空間(-Xmx)是物理內(nèi)存的1/4。能夠運(yùn)用JVM供給的-Xmn-Xms-Xmx等選項(xiàng)可進(jìn)行設(shè)置。
例如:java-jar-Xmn16m-Xms64m-Xmx128mMyApp.jar
假如HeapSize設(shè)置偏小,除了這些反常信息外,還會(huì)發(fā)現(xiàn)程序的響應(yīng)速度變慢了。GC占用了更多的時(shí)刻,而運(yùn)用分配到的履行時(shí)刻較少。
HeapSize最大不要超越可用物理內(nèi)存的80%,一般的要將-Xms和-Xmx選項(xiàng)設(shè)置為相同,而-Xmn為1/4的-Xmx值。
Heapsize的-Xms-Xmn設(shè)置不要超出物理內(nèi)存的巨細(xì)。不然會(huì)提示“ErroroccurredduringinitializationofVMCouldnotreserveenoughspaceforobjectheap”。
==========================================================
通過(guò)一個(gè)晚上的盡力終于完成了一個(gè)文件替換指定字符串的程序,可是由于我要替換的全站程序html文件太多,所以eclipse下邊老是在一個(gè)目錄完畢后報(bào)出java.lang.OutOfMemoryError:Javaheapspace的反常,然后就潰散了。
我一想肯定是頻頻操作形成來(lái)不及收回,所以在每個(gè)循環(huán)之后加上一個(gè)Thread.sleep(1000),發(fā)現(xiàn)仍是到那個(gè)目錄下就死掉,所以把1000改成5000,仍是到那里死掉,我想或許不是來(lái)不及收回這么簡(jiǎn)略,或許sun的JVM里面剛好關(guān)于這種狀況不釋放也有或許。
接著我又把發(fā)動(dòng)的參數(shù)添上一個(gè)-Xmx256M,這回就能夠了。
想一想,仍是關(guān)于廢物收回的原理不太了解,就在網(wǎng)上查了一下,發(fā)現(xiàn)了幾篇不錯(cuò)的文章。
http://java.ccidnet.com/art/3539/20060314/476073_1.html
http://www.pconline.com.cn/pcedu/empolder/gj/java/0509/701281.html
還有:Java堆的管理—廢物收回提到一下幾點(diǎn),很不錯(cuò),或許能夠作為寫程序時(shí)分的原則:
(1)不要試圖去假定廢物搜集產(chǎn)生的時(shí)刻,這一切都是未知的。比方,辦法中的一個(gè)暫時(shí)目標(biāo)在辦法調(diào)用完畢后就變成了無(wú)用目標(biāo),這個(gè)時(shí)分它的內(nèi)存就能夠被釋放。
(2)Java中供給了一些和廢物搜集打交道的類,并且供給了一種強(qiáng)行履行廢物搜集的辦法–調(diào)用System.gc(),但這同樣是個(gè)不確定的辦法。Java中并不確保每次調(diào)用該辦法就必定能夠發(fā)動(dòng)廢物搜集,它只不過(guò)會(huì)向JVM宣布這樣一個(gè)請(qǐng)求,到底是否真實(shí)履行廢物搜集,一切都是個(gè)未知數(shù)。
(3)挑選合適自己的廢物搜集器。一般來(lái)說(shuō),假如體系沒(méi)有特殊和嚴(yán)苛的性能要求,能夠采用JVM的缺省選項(xiàng)。不然能夠考慮運(yùn)用有針對(duì)性的廢物收集器,比方增量搜集器就比較合適實(shí)時(shí)性要求較高的體系之中。體系具有較高的配置,有比較多的擱置資源,能夠考慮運(yùn)用并行標(biāo)記/鏟除搜集器。
(4)關(guān)鍵的也是難把握的問(wèn)題是內(nèi)存泄漏。良好的編程習(xí)慣和謹(jǐn)慎的編程態(tài)度永遠(yuǎn)是最重要的,不要讓自己的一個(gè)小過(guò)錯(cuò)導(dǎo)致內(nèi)存出現(xiàn)大縫隙。
(5)盡早釋放無(wú)用目標(biāo)的引證。
大多數(shù)程序員在運(yùn)用暫時(shí)變量的時(shí)分,都是讓引證變量在退出活動(dòng)域(scope)后,主動(dòng)設(shè)置為null,暗示廢物搜集器來(lái)搜集該目標(biāo),還必須留意該引證的目標(biāo)是否被監(jiān)聽(tīng),假如有,則要去掉監(jiān)聽(tīng)器,然后再賦空值。
便是說(shuō),關(guān)于頻頻請(qǐng)求內(nèi)存和釋放內(nèi)存的操作,仍是自己操控一下比較好,可是System.gc()的辦法不必定適用,最好運(yùn)用finallize強(qiáng)制履行或許寫自己的finallize辦法。
================================================
tomcat
遇到TOMCAT出錯(cuò):java.lang.OutOfMemoryError:Javaheapspace,所以查了材料,找到了解決辦法:
IfJavarunsoutofmemory,thefollowingerroroccurs:
Exceptioninthread”main”java.lang.OutOfMemoryError:Javaheapspace
Javaheapsizecanbeincreasedasfollows:
java-Xms-Xmx
Defaultsare:
java-Xms32m-Xmx128m
假如你用win
/tomcat/bin/catalina.bat加上下面的指令:
setJAVA_OPTS=-Xms32m-Xmx256m
假如你用unix/linux
/tomcat/bin/catalina.sh加上下面的指令:
JAVA_OPTS=”-Xms32m-Xmx256m”
jvm內(nèi)存檢查與剖析東西
業(yè)界有許多強(qiáng)大的javaprofile的東西,比方Jporfiler,yourkit,這些收費(fèi)的東西我就不想說(shuō)了,想說(shuō)的是,其實(shí)java自己就供給了許多內(nèi)存監(jiān)控的小東西,下面列舉的東西僅僅一小部分,細(xì)心研究下jdk的東西,仍是蠻有意思的呢:)
1:gc日志輸出
在jvm發(fā)動(dòng)參數(shù)中參加-XX:+PrintGC-XX:+PrintGCDetails-XX:+PrintGCTimestamps-XX:+PrintGCApplicationStopedTime,jvm將會(huì)依照這些參數(shù)次序輸出gc概要信息,詳細(xì)信息,gc時(shí)刻信息,gc形成的運(yùn)用暫停時(shí)刻。假如在剛才的參數(shù)后邊參加參數(shù)-Xloggc:文件途徑,gc信息將會(huì)輸出到指定的文件中。其他參數(shù)還有
-verbose:gc和-XX:+PrintTenuringDistribution等。
2:jconsole
jconsole是jdk自帶的一個(gè)內(nèi)存剖析東西,它供給了圖形界面。能夠檢查到被監(jiān)控的jvm的內(nèi)存信息,線程信息,類加載信息,MBean信息。
jconsole坐落jdk目錄下的bin目錄,在windows下是jconsole.exe,在unix和linux下是jconsole.sh,jconsole能夠監(jiān)控本地運(yùn)用,也能夠監(jiān)控長(zhǎng)途運(yùn)用。要監(jiān)控本地運(yùn)用,履行jconsolepid,pid便是運(yùn)轉(zhuǎn)的java進(jìn)程id,假如不帶上pid參數(shù),則履行jconsole指令后,會(huì)看到一個(gè)對(duì)話框彈出,上面列出了本地的java進(jìn)程,能夠選擇一個(gè)進(jìn)行監(jiān)控。假如要長(zhǎng)途監(jiān)控,則要在長(zhǎng)途服務(wù)器的jvm參數(shù)里參加一些東西,由于jconsole的長(zhǎng)途監(jiān)控基于jmx的,關(guān)于jconsole詳細(xì)用法,請(qǐng)見(jiàn)專門介紹jconsle的文章,我也會(huì)在博客里專門詳細(xì)介紹jconsole。
3:jviusalvm
在JDK6update7之后,jdk推出了別的一個(gè)東西:jvisualvm,java可視化虛擬機(jī),它不光供給了jconsole相似的功用,還供給了jvm內(nèi)存和cpu實(shí)時(shí)確診,還有手動(dòng)dump出jvm內(nèi)存狀況,手動(dòng)履行g(shù)c。
和jconsole一樣,運(yùn)轉(zhuǎn)jviusalvm,在jdk的bin目錄下履行jviusalvm,windows下是jviusalvm.exe,linux和unix下是jviusalvm.sh。
4:jmap
jmap是jdk自帶的jvm內(nèi)存剖析的東西,坐落jdk的bin目錄。jdk1.6中jmap指令用法:
Usage:
jmap-histo<pid>(toconnecttorunningprocessandprinthistogramofjavaobjectheap
jmap-dump:<dump-options><pid>(toconnecttorunningprocessanddumpjavaheap)
dump-options:format=bbinarydefaultfile=<file>
dumpheapto<file>
Example:jmap-dump:format=b,file=heap.bin<pid>
jmap-histo在屏幕上顯現(xiàn)出指定pid的jvm內(nèi)存狀況。以我本機(jī)為例,履行該指令,屏幕顯現(xiàn):
1:242062791864<constMethodKlass>
2:223712145216[C
3:242061940648<methodKlass>
4:19511364496<constantPoolKlass>
5:265431282560<symbolKlass>
6:63771081744[B
7:1793909688<constantPoolCacheKlass>
8:1471614624<instanceKlassKlass>
9:14581548336[Ljava.lang.Object;
10:3863513640[I
11:20677496248java.lang.String
12:3621312776[Ljava.util.HashMap$Entry;
13:3335266800java.lang.reflect.Method
14:8256264192java.io.ObjectStreamClass$WeakClassKey
15:7066226112java.util.TreeMap$Entry
16:2355173304[S
17:1687161952java.lang.Class
18:2769150112[[I
19:3563142520java.util.HashMap
20:5562133488java.util.HashMap$Entry
Total23901917140408
為了便利檢查,我刪掉了一些行。從上面的信息很簡(jiǎn)略看出,#instance指的是目標(biāo)數(shù)量,#bytes指的是這些目標(biāo)占用的內(nèi)存巨細(xì),classname指的是目標(biāo)類型。
再看jmap的dump選項(xiàng),這個(gè)選項(xiàng)是將jvm的堆中內(nèi)存信息輸出到一個(gè)文件中,在我本機(jī)履行
jmap-dump:file=c:\dump.txt340
留意340是我本機(jī)的java進(jìn)程pid,dump出來(lái)的文件比較大有10幾M,并且我僅僅開了tomcat,跑了一個(gè)很簡(jiǎn)略的運(yùn)用,且沒(méi)有任何拜訪,能夠想象,大型繁忙的服務(wù)器上,dump出來(lái)的文件該有多大。需求知道的是,dump出來(lái)的文件信息是很原始的,絕不合適人直接觀看,而jmap-histo顯現(xiàn)的內(nèi)容又太簡(jiǎn)略,例如只顯現(xiàn)某些類型的目標(biāo)占用多大內(nèi)存,以及這些目標(biāo)的數(shù)量,可是沒(méi)有更詳細(xì)的信息,例如這些目標(biāo)分別是由誰(shuí)創(chuàng)立的。那這么說(shuō),dump出來(lái)的文件有什么用呢?當(dāng)然有用,由于有專門剖析jvm的內(nèi)存dump文件的東西。
5:jhat
上面說(shuō)了,有許多東西都能剖析jvm的內(nèi)存dump文件,jhat便是sunjdk6及以上版別自帶的東西,坐落jdk的bin目錄,履行jhat-J-Xmx512m[file],file便是dump文件途徑。jhat內(nèi)置一個(gè)簡(jiǎn)略的web服務(wù)器,此指令履行后,jhat在指令行里顯現(xiàn)剖析成果的拜訪地址,能夠用-port選項(xiàng)指定端口,詳細(xì)用法能夠履行jhat-heap檢查協(xié)助信息。拜訪指定地址后,就能看到頁(yè)面上顯現(xiàn)的信息,比jmap-histo指令顯現(xiàn)的豐厚得多,更為詳細(xì)。
6:eclipse內(nèi)存剖析器
上面說(shuō)了jhat,它能剖析jvm的dump文件,可是全部是文字顯現(xiàn),eclipsememoryanalyzer,是一個(gè)eclipse供給用于剖析jvm堆dump的插件,網(wǎng)址為http://www.eclipse.org/mat,它的剖析速度比jhat快,剖析成果是圖形界面顯現(xiàn),比jhat的可讀性更高。其實(shí)jvisualvm也能夠剖析dump文件,也是有圖形界面顯現(xiàn)的。
7:jstat
假如說(shuō)jmap傾向于剖析jvm內(nèi)存中目標(biāo)信息的話,那么jsta便是傾向于剖析jvm內(nèi)存的gc狀況。都是jvm內(nèi)存剖析東西,但明顯,它們是從不同維度來(lái)剖析的。jsat常用的參數(shù)有許多,如-gc,-gcutil,-gccause,這些選項(xiàng)詳細(xì)效果可檢查jsat協(xié)助信息,我經(jīng)常用-gcutil,這個(gè)參數(shù)的效果不斷的顯現(xiàn)當(dāng)時(shí)指定的jvm內(nèi)存的廢物搜集的信息。
我在本機(jī)履行jstat-gcutil34010000,這個(gè)指令是每個(gè)10秒鐘輸出一次jvm的gc信息,10000指的是間隔時(shí)刻為10000毫秒。屏幕上顯現(xiàn)如下信息(我只取了第一行,由于是按的必定頻率顯現(xiàn),所以實(shí)際履行的時(shí)分,會(huì)有許多行):
S0S1EOPYGCYGCTFGCFGCTGCT
54.620.0042.8743.5286.2417925.093337.67012.763
額。。。怎么說(shuō)呢,要看懂這些信息代表什么意思,還必須對(duì)jvm的gc機(jī)制有必定的了解才行啊。其實(shí)假如對(duì)sun的hotspotjvm的gc比較了解的人,應(yīng)該很簡(jiǎn)略看懂這些信息,可是不清楚gc機(jī)制的人,有點(diǎn)不可思議,所以在這里我仍是先講講sun的jvm的gc機(jī)制吧。說(shuō)到gc,其實(shí)不只僅僅僅java的概念,其實(shí)在java之前,就有許多言語(yǔ)有g(shù)c的概念了,gc嘛便是廢物搜集的意思,更多的是一種算法性的東西,而跟詳細(xì)言語(yǔ)沒(méi)太大關(guān)系,所以關(guān)于gc的歷史,gc的干流算法我就不講了,那扯得太遠(yuǎn)了,扯得太遠(yuǎn)了便是扯淡。sun現(xiàn)在的jvm,內(nèi)存的管理模型是分代模型,所以gc當(dāng)然是分代搜集了。分代是什么意思呢?便是將目標(biāo)依照生命周期分成三個(gè)層次,分別是:新生代,舊生代,耐久代。目標(biāo)剛開始分配的時(shí)分,大部分都在新生代,當(dāng)新生代gc提交被觸發(fā)后了,履行一次新生代范圍內(nèi)的gc,這叫minorgc,假如履行了幾回minorgc后,還有目標(biāo)存活,將這些目標(biāo)轉(zhuǎn)入舊生代,由于這些目標(biāo)現(xiàn)已通過(guò)了組織的重重檢測(cè)了哇。舊生代的gc頻率會(huì)更低一些,假如舊生代履行了gc,那便是fullgc,由于不是局部gc,而是全內(nèi)存范圍的gc,這會(huì)形成運(yùn)用中止,由于全內(nèi)存搜集,必須封閉內(nèi)存,不許有新的目標(biāo)分配到內(nèi)存,耐久代便是一些jvm期間,根本不會(huì)消失的目標(biāo),例如class的界說(shuō),jvm辦法區(qū)信息,例如靜態(tài)塊。需求首要的是,新生代里又分了三個(gè)空間:eden,susvivor0,susvivor1,按字面上來(lái)了解,便是伊甸園區(qū),幸存1區(qū),幸存2區(qū)。新目標(biāo)分配在eden區(qū)中,eden區(qū)滿時(shí),采用標(biāo)記-復(fù)制算法,即檢查出eden區(qū)存活的目標(biāo),并將這些目標(biāo)復(fù)制到是s0或s1中,然后清空eden區(qū)。jvm的gc說(shuō)開來(lái),不僅僅這么簡(jiǎn)略,例如還有串行搜集,并行搜集,并發(fā)搜集,還有著名的火車算法,不過(guò)那說(shuō)得太遠(yuǎn)了,現(xiàn)在對(duì)這個(gè)有大致了解就好。說(shuō)到這里,再來(lái)看一下上面輸出的信息:
S0S1EOPYGCYGCTFGCFGCTGCT
54.620.0042.8743.5286.2417925.093337.67012.763
S0:新生代的susvivor0區(qū),空間運(yùn)用率為54..62%
S1:新生代的susvivor1區(qū),空間運(yùn)用率為0.00%(由于還沒(méi)有履行第二次minor搜集)
E:eden區(qū),空間運(yùn)用率42.87%
O:舊生代,空間運(yùn)用率43.52%
P:耐久帶,空間運(yùn)用率86.24%
YGC:minorgc履行次數(shù)1792次
YGCT:minorgc消耗的時(shí)刻5.093毫秒
FGC:fullgc履行次數(shù)33
FGCT:fullgc消耗的時(shí)刻7.670毫秒
GCT:gc消耗的總時(shí)刻12.763毫秒
廣州天河區(qū)珠江新城富力盈力大廈北塔2706
020-38013166(網(wǎng)站咨詢專線)
400-001-5281 (售后服務(wù)熱線)
深圳市坂田十二橡樹莊園F1-7棟
Site/ http://www.szciya.com
E-mail/ itciya@vip.163.com
品牌服務(wù)專線:400-001-5281
長(zhǎng)沙市天心區(qū)芙蓉中路三段398號(hào)新時(shí)空大廈5樓
聯(lián)系電話/ (+86 0731)88282200
品牌服務(wù)專線/ 400-966-8830
旗下運(yùn)營(yíng)網(wǎng)站:
Copyright ? 2016 廣州思洋文化傳播有限公司,保留所有權(quán)利。 粵ICP備09033321號(hào)