JVM的基本介紹以及垃圾回收
JVM java虛擬機(jī)
JVM
java虛擬機(jī)是一個(gè)可執(zhí)行java字節(jié)碼的虛擬機(jī)進(jìn)程。Java虛擬機(jī)本質(zhì)上就是一個(gè)程序,java源文件被編譯成能被java虛擬機(jī)執(zhí)行的字節(jié)碼文件,當(dāng)它在命令行上啟動(dòng)的時(shí)候,就開始執(zhí)行保存在某字節(jié)碼文件中的指令。Java語言的可移植性正是建立在Java虛擬機(jī)的基礎(chǔ)上。任何平臺(tái)只要裝有針對(duì)于該平臺(tái)的Java虛擬機(jī),字節(jié)碼文件(.class)就可以在該平臺(tái)上運(yùn)行。這就是“一次編譯,多次運(yùn)行”。
java文件,通過編譯器變成了.class文件,接下來類加載器又將這些class文件加載到JVM中。其實(shí)可以一句話來解釋,類的加載指的是將類的.class文件二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,將其放在運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),
然后在堆區(qū)創(chuàng)建一個(gè) java.lang.Class對(duì)象,用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。
jvm主要組成部分及其作用
我們常說的jvm的主要組成,指的是運(yùn)行時(shí)數(shù)據(jù)區(qū)。但是,其他它還包括其他部分,執(zhí)行引擎、本地接口、類加載子系統(tǒng)
jvm主要構(gòu)成:方法區(qū)、Java堆、Java虛擬機(jī)棧、本地方法區(qū)、程序計(jì)數(shù)器等。
JAVA Heap:堆,放的是new的對(duì)象,數(shù)組,大數(shù)據(jù)的東西;運(yùn)行時(shí)的數(shù)據(jù)
JVM Stack: jvm棧,控制方法怎么調(diào)度,控制應(yīng)用程序怎么運(yùn)行的
Native Method Stack:本地方法棧,本地的方法棧,調(diào)用本地服務(wù)
Method Area:方法區(qū),放的是運(yùn)行時(shí)的方法
其中方法區(qū)和堆是由所有線程共享,
而Java棧、本地方法區(qū)、程序計(jì)數(shù)器是線程私有。
我們常說的內(nèi)存溢出,指的就是 java堆(Heap) 內(nèi)存不夠了。
JVM Stack jvm棧區(qū),每啟動(dòng)個(gè)線程,jvm就為該線程分配一個(gè)棧區(qū),線程調(diào)用方法時(shí)和方法返回時(shí)進(jìn)行入棧和出棧的操作。
Native Stack 本地方法棧區(qū),與jvm stack類似,不過此區(qū)域是為調(diào)用本地方法服務(wù)的
Java Heap java的所有對(duì)象實(shí)例,數(shù)組等。
程序計(jì)數(shù)寄存器 ,每個(gè)線程自己的計(jì)數(shù)寄存器,存儲(chǔ)當(dāng)前線程執(zhí)行字節(jié)碼的地址。
Program Counter Register:程序計(jì)數(shù)器:
每個(gè)線程在創(chuàng)建后,都會(huì)產(chǎn)生自己的程序計(jì)數(shù)器和棧幀。程序計(jì)數(shù)器用來存放執(zhí)行指令的偏移量和行號(hào)指示器等。
線程執(zhí)行或者恢復(fù)都要依賴程序計(jì)數(shù)器。程序計(jì)數(shù)器在各個(gè)線程之間互不影響。此區(qū)域也不會(huì)發(fā)生內(nèi)存溢出異常,程序計(jì)數(shù)器是占用空間最小的內(nèi)存區(qū)域,不會(huì)出現(xiàn)OOM。
主要記錄當(dāng)前線程正在執(zhí)行的方法的指令地址。方便線程切換后能恢復(fù)到下一條指令的位置,如果是執(zhí)行native方法,則該計(jì)數(shù)器為空。
程序計(jì)數(shù)器(后文簡稱PCR)有兩個(gè)作用:
- 字節(jié)碼解釋器通過改變PCR依次讀取指令,實(shí)現(xiàn)代碼的流程控制,如順序執(zhí)行、選擇、循環(huán)、異常處理
- 多線程情況下,PCR用于記錄當(dāng)前線程的執(zhí)行位置,從而當(dāng)線程被切換回來的時(shí)候,能夠知道該線程上次運(yùn)行到哪兒了。
JVM Stack: jvm棧
java虛擬機(jī)棧也叫線程棧
虛擬機(jī)棧包含:
1、局部變量表
2、動(dòng)態(tài)連接
3、操作棧
4、方法返回地址
1、局部變量表
存放方法參數(shù)和局部變量
相對(duì)于類屬性的變量準(zhǔn)備階段和初始化階段,局部變量沒有準(zhǔn)備階段,必需顯式初始化。
如果是非靜態(tài)方法,則在index[0]位置存儲(chǔ)的是方法所屬對(duì)象的實(shí)例引用,隨后存儲(chǔ)的是參數(shù)和局部變量。
2、動(dòng)態(tài)連接
每個(gè)棧幀中包含一個(gè)在常量池中,對(duì)當(dāng)前方法的引用。目的是支持方法調(diào)用過程的動(dòng)態(tài)連接。
3、方法返回地址:
方法執(zhí)行的時(shí)候,有兩種退出情況:
正常退出
正常執(zhí)行到任何方法的返回字節(jié)碼指令,如RETURN、IRETURN等。
異常退出
無論何種,都將返回至方法當(dāng)前被調(diào)用的位置。方法退出的過程相當(dāng)于彈出當(dāng)前棧幀。
3、操作棧
本地方法?;旧系韧趈ava虛擬機(jī)棧。
堆和棧是程序運(yùn)行的關(guān)鍵,很有必要把他們癿關(guān)系說清楚。
棧是運(yùn)行時(shí)的單位,而堆是存儲(chǔ)的單位。
棧解決程序的運(yùn)行問題,即程序如何執(zhí)行,或者說如何處理數(shù)據(jù);
堆解決的是數(shù)據(jù)存儲(chǔ)的問題,即數(shù) 據(jù)怎么放、放在哪兒。
在 Java 中一個(gè)線程就會(huì)相應(yīng)有一個(gè)線程棧與之對(duì)應(yīng),這點(diǎn)很容易理解,因?yàn)椴煌木€程執(zhí)行邏輯有 所不同,因此需要一個(gè)獨(dú)立的線程棧。
而堆則是所有線程共享的。
棧因?yàn)槭沁\(yùn)行單位,因此里面存儲(chǔ) 的信息都是跟當(dāng)前線程(或程序)相關(guān)信息的。包括局部變量、程序運(yùn)行狀態(tài)、方法返回值等等;而 堆只負(fù)責(zé)存儲(chǔ)對(duì)象信息。
元數(shù)據(jù)區(qū)(Matespace):
包括:
常量池、類元信息、方法元信息
園區(qū)
JDK1.8之前叫持久代;1.8之后叫園區(qū)。
園區(qū)放的是方法常量
(以下非必需)
為什么要把堆和棧區(qū)分出來呢?棧中不是也可以存儲(chǔ)數(shù)據(jù)嗎?
第一,從軟件設(shè)計(jì)的角度看,棧代表了處理邏輯,而堆代表了數(shù)據(jù)。這樣分開,使得處理邏輯更為清 晰。分而治之的思想。這種隔離、模塊化的思想在軟件設(shè)計(jì)的方方面面都有體現(xiàn)。
第二,堆與棧的分離,使得堆中的內(nèi)容可以被多個(gè)棧共享(也可以理解為多個(gè)線程訪問同一個(gè)對(duì)象)。 這種共享的收益是很多的。一方面這種共享提供了一種有效的數(shù)據(jù)交互方式(如:共享內(nèi)存),另一方 面,堆中的共享常量和緩存可以被所有棧訪問,節(jié)省了空間。
第三,棧因?yàn)檫\(yùn)行時(shí)的需要,比如保存系統(tǒng)運(yùn)行的上下文,需要進(jìn)行地址段的劃分。由于棧只能向上 增長,因此就會(huì)限制住棧存儲(chǔ)內(nèi)容的能力。而堆不同,堆中的對(duì)象是可以根據(jù)需要?jiǎng)討B(tài)增長的,因此 棧與堆的拆分,使得動(dòng)態(tài)增長成為可能,相應(yīng)棧中只需記錄堆中的一個(gè)地址即可。
第四,面向?qū)ο缶褪嵌雅c棧的完美結(jié)合。其實(shí),面向?qū)ο蠓绞降某绦蚺c以前結(jié)構(gòu)化的程序在執(zhí)行上沒 有任何區(qū)別。但是,面向?qū)ο蟮囊?,使得?duì)待問題的思考方式發(fā)生了改變,而更接近于自然方式的思考。
當(dāng)我們把對(duì)象拆開,你會(huì)發(fā)現(xiàn),對(duì)象的屬性其實(shí)就是數(shù)據(jù),存放在堆中;而對(duì)象的行為(方法), 就是運(yùn)行邏輯,放在棧中。
我們?cè)诰帉憣?duì)象的時(shí)候,其實(shí)即編寫了數(shù)據(jù)結(jié)構(gòu),也編寫了處理數(shù)據(jù)的邏輯。
在 Java 中,Main 函數(shù)就是棧的起始點(diǎn),也是程序的起始點(diǎn)。
程序要運(yùn)行總是有一個(gè)起點(diǎn)的。同 C 語言一樣,java 中的 Main 就是那個(gè)起點(diǎn)。無論什么java 程序, 找到 main 就找到了程序執(zhí)行的入口:
堆:
運(yùn)行時(shí)的數(shù)據(jù),也就是new的對(duì)象和一些數(shù)組。
運(yùn)行時(shí)最大的數(shù)據(jù),就在堆內(nèi)。
Jvm heap內(nèi)存空間劃分
堆內(nèi)(放的是對(duì)象,數(shù)組)=臨時(shí)數(shù)據(jù),用完就沒啦
年輕代:eden +s1 +s0(eden:s1 :s0默認(rèn)比例:8:1:1 )
老年代:(年輕代:老年代默認(rèn)比例:1:2)
s0與s1大小相等,位置互換
堆外(放的是方法,類,常量)
Eden(伊甸園區(qū)):
所有新new的對(duì)象和數(shù)組,是在伊甸園區(qū)產(chǎn)生的,內(nèi)存分配是在伊甸園區(qū)進(jìn)行的。
在伊甸園區(qū)new 一個(gè)對(duì)象,如果這個(gè)對(duì)象被用到了,那么他的引用就+1。應(yīng)用的越多,占內(nèi)存越多。
當(dāng)伊甸園區(qū)內(nèi)存被占滿時(shí),就不能再new對(duì)象,程序依賴對(duì)象,所以程序也就不能運(yùn)行。java應(yīng)用程序?yàn)榱四芾^續(xù)運(yùn)行,就要干掉那些不被引用的對(duì)象,對(duì)這些不被引用的對(duì)象進(jìn)行垃圾回收。
現(xiàn)代虛擬機(jī)一般使用的內(nèi)存回收策略是分代收集,即把對(duì)象分為兩代,新生代(年輕代)使用復(fù)制算法回收內(nèi)存,老年代使用標(biāo)志-整理算方法回收內(nèi)存。
垃圾回收的時(shí)候,如何判斷該對(duì)象是否可以被回收:
有2種算法
算法一:引用計(jì)數(shù)(已經(jīng)被廢棄了)
引用計(jì)數(shù),對(duì)象被創(chuàng)建后,有個(gè)計(jì)數(shù)器。只要對(duì)象被引用,那么計(jì)數(shù)器就+1,再次被引用,就再+1,如果方法執(zhí)行完成,對(duì)象不被引用了,計(jì)數(shù)器就-1。
當(dāng)計(jì)數(shù)器為0時(shí),該對(duì)象沒有被引用,就可以被垃圾回收了。
引用計(jì)數(shù)算法,有一個(gè)弊端,就是在執(zhí)行遞歸的時(shí)候,就沒有辦法計(jì)算了。
算法二:尋根判斷
尋根判斷,從對(duì)象的根結(jié)點(diǎn)開始去找,是否被引用,如果跟節(jié)點(diǎn)都沒有引用,那么就是沒有被引用。
被引用的對(duì)象,稱為存活對(duì)象。
未被引用的對(duì)象,稱為非存活對(duì)象。
當(dāng)伊甸園區(qū)被占滿時(shí),觸發(fā)GC(垃圾回收 Garbage Collection)。
GC分兩步,第1步標(biāo)記,對(duì)非存活對(duì)象進(jìn)行標(biāo)記。第2步清掃,將非存活對(duì)象從內(nèi)存中干掉,釋放內(nèi)存,同時(shí)將存活的對(duì)象移到存活區(qū)中。
YGC
發(fā)生在年輕代。
在YGC之前,伊甸園區(qū)是滿的,無法new對(duì)象,程序無法運(yùn)行。
YGC之后,伊甸園區(qū)就空了,就可以繼續(xù)new對(duì)象。
YGC整個(gè)流程:
第一次gc,,對(duì)存活的對(duì)象進(jìn)行標(biāo)記,然后將Eden區(qū)的存活對(duì)象,存活區(qū)S0
第二次gc,使用尋根判斷的算法,對(duì)存活的對(duì)象進(jìn)行標(biāo)記,然后將Eden區(qū)的存活對(duì)象,移到存活區(qū)S0
步驟1:new的對(duì)象、數(shù)組,直接進(jìn)入eden園區(qū)。
步驟2:eden園區(qū)滿了,觸發(fā)ygc,對(duì)【eden園區(qū)】的對(duì)象和數(shù)組進(jìn)行標(biāo)記(使用尋根判斷的算法),清掃(將沒有引用的對(duì)象干掉,被引用的移到其中一個(gè)存活區(qū)s0);
eden園區(qū)第二次滿了,再次觸發(fā)ygc,對(duì)【eden園區(qū)和存活區(qū)s0】的對(duì)象和數(shù)組進(jìn)行標(biāo)記,清掃將沒有引用的干掉,被引用的對(duì)象和數(shù)組移到在另一個(gè)存活區(qū)s1(這里用的是復(fù)制算法)
步驟3:fgc,全gc,堆內(nèi)存和持久代均gc。將沒有的干掉,有用的放到老年代。
年輕代里面的兩個(gè)存活區(qū),大小相等,且同一時(shí)間只有一個(gè)存活區(qū)有對(duì)象,另一個(gè)存活區(qū)為空。gc之前,存活區(qū)s0有對(duì)象,s1為空,一次gc之后,s0為空,s1存放對(duì)象。
對(duì)象進(jìn)入老年代原則:
大對(duì)象直接進(jìn)入老年代長期存活的對(duì)象進(jìn)入老年代動(dòng)態(tài)年齡判斷一次Young GC時(shí)數(shù)據(jù)放到存活區(qū),但是存活區(qū)滿了導(dǎo)致放不下去此時(shí)直接進(jìn)入老年代(盡可能避免這種情況)
1、大對(duì)象直接進(jìn)入老年代
在堆中分配的大對(duì)象直接挪到老年代
大對(duì)象是指需要大量連續(xù)內(nèi)存空間的對(duì)象,例如很長的字符串以及數(shù)組。
虛擬機(jī)設(shè)置了一個(gè)-XX:PretenureSizeThreshold參數(shù),有個(gè)默認(rèn)值,令大于這個(gè)設(shè)置的對(duì)象直接在老年代分配,這個(gè)值是可以修改的。
目的就是為了防止大對(duì)象在Eden空間和Survivor空間來回大量復(fù)制,大對(duì)象很容易把伊甸園區(qū)占滿,導(dǎo)致YGC頻繁。
2、長期存活的對(duì)象進(jìn)入老年代(伴隨YGC產(chǎn)生的)
虛擬機(jī)給每個(gè)對(duì)象定義了一個(gè)對(duì)象年齡(Age)計(jì)數(shù)器,如果對(duì)象在Eden區(qū)出生并經(jīng)過第一次YGC/Mintor GC后仍然存活,并且能被Survivor接納,并被移動(dòng)到Survivor空間上,那么該對(duì)象年齡將被設(shè)置為1。
對(duì)象在Survivor區(qū)中每熬過一次YGC/Minor GC,年齡就加一,當(dāng)他的年齡增加到一定程度,就會(huì)被移動(dòng)到老年代(年齡值默認(rèn)為15)。
對(duì)象晉升老年代的閾值可以通過-XX:MaxTenuringThreshold設(shè)置。
3、動(dòng)態(tài)年齡判斷并進(jìn)入老年代(伴隨YGC產(chǎn)生的)
為了更好的適應(yīng)不同程序的內(nèi)存狀況,虛擬機(jī)并不是永遠(yuǎn)要求對(duì)象的年齡必須達(dá)到MaxTenuringThreshold才會(huì)晉升到老年代。
如果在Survivor空間中相同年齡的所有對(duì)象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對(duì)象就可以直接進(jìn)入老年代,無需達(dá)到MaxTensuringThreshold的要求年齡。
(相同age對(duì)象大小之和>1/2存活區(qū)(即s0或者s1)則所有>=age的對(duì)象就會(huì)進(jìn)入老年代)
舉個(gè)栗子:
比如:MaxTenuringThreshold 為15,Survivor內(nèi)存大小為100M。age 為1的,所有對(duì)象大小之和為10M。age 為5的,所有對(duì)象大小之和為51M。age為6的,所有對(duì)象大小之和為5M.
因?yàn)閍ge 為5的對(duì)象所占內(nèi)存之和已經(jīng)超過了Survivor空間的一半,所以age為5,和age大于5的對(duì)象,都要移到老年代(沒有age達(dá)到15的限制)
4、一次Young GC時(shí)數(shù)據(jù)放到存活區(qū),但是存活區(qū)滿了導(dǎo)致放不下去此時(shí)直接進(jìn)入老年代
盡可能避免這種情況,如果對(duì)象直接從Eden區(qū)到老年代,那么存活區(qū)就沒有什么存在的意義了,之所以設(shè)置存活區(qū),就是為了將沒有引用的對(duì)象更早的回收掉,將內(nèi)存騰出來。
Full GC
當(dāng)老年代滿了之后,觸發(fā)Full GC。
Full GC 范圍:
整個(gè)堆內(nèi)存(年輕代+老年代)+園數(shù)據(jù)區(qū)
對(duì)堆的回收:
標(biāo)記--清掃
對(duì)堆標(biāo)記,對(duì)象是否被引,被引用的為存活對(duì)象。
對(duì)園數(shù)據(jù)回收:
標(biāo)記--清掃
標(biāo)記類,哪些類失效了。
回收,將失效的類卸載掉。
FGC時(shí)長,大小跟內(nèi)存大小有關(guān)系,內(nèi)存大,則FGC時(shí)間長。
時(shí)長不太好控制,但是我們可以控制FGC頻次。
當(dāng)老年代和年輕代,被存活的對(duì)象占滿時(shí)(GC也不能將這些存活的對(duì)象清理掉),在Eden就不能再創(chuàng)建新的對(duì)象,導(dǎo)致OOM。
http://www.itcdns.cn/skill/detail/1586233667857
一、OOM含義:
OOM,全稱“Out Of Memory”,意思是“內(nèi)存用完了”。 它來源于java.lang.OutOfMemoryError。
官方介紹為當(dāng)JVM因?yàn)闆]有足夠的內(nèi)存來為對(duì)象分配空間并且垃圾回收器也已經(jīng)沒有空間可回收時(shí),就會(huì)拋出 java.lang.OutOfMemoryError :···
(注意:這是個(gè)很嚴(yán)重的問題,因?yàn)檫@個(gè)問題已經(jīng)嚴(yán)重到不足以被應(yīng)用處理)。
gc的觸發(fā)條件
觸發(fā)條件:
YGC:
有且只有這一種情況,eden滿了,觸發(fā)gc
FGC:
1、老年代滿了
2、園區(qū)某些類已經(jīng)失效了,在加載的找不到這個(gè)類,也會(huì)觸發(fā)FGC,去卸載這個(gè)類,釋放這個(gè)類。
3、空間擔(dān)保原則(主要觸發(fā)fgc的方式)
4、代碼里面顯示調(diào)用
5、jmap dump
內(nèi)存擔(dān)保機(jī)制
現(xiàn)代虛擬機(jī)把新生代分為三個(gè)區(qū)域,一個(gè)Eden區(qū)域,兩個(gè)Survivor區(qū)域,Eden區(qū)域與Survivor區(qū)域的比例大小是8:1,虛擬機(jī)在YGC/Minor GC時(shí)在新生代采用復(fù)制算法,將存活對(duì)象復(fù)制到一個(gè)Survivor上面,如果Survivor空間不夠用時(shí),就需要老年代進(jìn)行分配擔(dān)保。
在發(fā)生Minor GC之前虛擬機(jī)會(huì)先檢查老年代最大可用的連續(xù)空間是否大于新生代對(duì)象的總空間。如果這個(gè)條件成立,那么Minor GC可以確保是安全的。如果不成立,虛擬機(jī)會(huì)查看HandlePromotionFailure設(shè)置值是否允許擔(dān)保失敗。如果允許,虛擬機(jī)會(huì)繼續(xù)檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代的平均年齡(因?yàn)槭孪炔恢来婊顚?duì)象的內(nèi)存空間,所以取了平均值)。若果大于,虛擬機(jī)會(huì)嘗試進(jìn)行一次Minor GC,但是這次Minor GC存在風(fēng)險(xiǎn)。如果小于,或者HandlePromotionFailure不允許擔(dān)保,那這次也要改為Full GC
空間擔(dān)保原則:
每次ygc的時(shí)候,都會(huì)往老年代里放對(duì)象。
根據(jù)歷史每次往老年代放的對(duì)象大小,根據(jù)一個(gè)算法,估算這一次要放對(duì)象大小。估算的數(shù)值,小于老年代剩余內(nèi)存,就執(zhí)行ygc。
如果大于老年代剩余空間,放棄本次ygc,直接fgc。
代碼里面顯示調(diào)用
代碼里寫了system.gc或者get run time .gc
fgc特別消耗cpu,盡可能把FGC頻次減少,最起碼要一小時(shí)以上
java進(jìn)程之間以及跟JVM是什么關(guān)系
1.程序的運(yùn)行是以進(jìn)程在內(nèi)存中的運(yùn)行形式體現(xiàn)的。當(dāng)你啟動(dòng)一個(gè)程序時(shí),系統(tǒng)會(huì)調(diào)用其對(duì)應(yīng)進(jìn)程進(jìn)入內(nèi)存運(yùn)行,圖中進(jìn)程的pid即為進(jìn)程的唯一標(biāo)識(shí)符。然后進(jìn)程之間是并發(fā)執(zhí)行的。準(zhǔn)確的說,你啟動(dòng)的是java程序,但系統(tǒng)運(yùn)行的是進(jìn)程,因?yàn)槌绦蚴庆o態(tài)的,進(jìn)程才是動(dòng)態(tài)的,也就是程序并不會(huì)進(jìn)入內(nèi)存運(yùn)行,而是其對(duì)應(yīng)進(jìn)程進(jìn)入內(nèi)存運(yùn)行。
2.是公用一個(gè)JVM的,這個(gè)就類似你電腦自己的操作系統(tǒng),打開兩個(gè)程序肯定是在同一個(gè)系統(tǒng)內(nèi)存中運(yùn)行的,原因就是我問題一中說的進(jìn)程是并發(fā)執(zhí)行的。
命令行啟動(dòng)的java程序是共用一個(gè)jvm的,啟動(dòng)一個(gè)程序就是在jvm中開啟一個(gè)進(jìn)程,每個(gè)進(jìn)程至少有一個(gè)線程,當(dāng)然可以有多個(gè)線程,
線程之間通信比較簡單,就像java書上講的一樣,但進(jìn)程間的通信復(fù)雜點(diǎn),如管道、內(nèi)存映射、內(nèi)存共享、消息隊(duì)列、socket等,你可以簡單理解為兩個(gè)進(jìn)程間沒關(guān)系
2個(gè)進(jìn)程肯定是2個(gè)jvm實(shí)例
二、監(jiān)控GC命令
1、jstat監(jiān)控Java進(jìn)程的GC情況
登陸服務(wù)器
ssh root@47.95.122.13
查看java進(jìn)程
ps -ef|grep java
監(jiān)控fgc次數(shù)和時(shí)間
jstat -gcutil 22893 2000
jstat -gcutil [Java的pid] 2000 20 (間隔2s,總共打印20次)
jstat -gcutil 22278 2000
查看gc的情況(內(nèi)存使用百分比及gc的總時(shí)間,gc次數(shù))
總結(jié)
到此這篇關(guān)于JVM的基本介紹以及垃圾回收的文章就介紹到這了,更多相關(guān)JVM垃圾回收內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring?@Transactional注解中常用參數(shù)詳解
這篇文章主要介紹了spring?@Transactional注解中常用參數(shù)詳解,事物注解方式:?@Transactional,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02Java中一維二維數(shù)組的靜態(tài)和動(dòng)態(tài)初始化
今天通過本文給大家分享Java中的數(shù)組,包括一維數(shù)組和二維數(shù)組的靜態(tài)初始化和動(dòng)態(tài)初始化問題,感興趣的朋友一起看看吧2017-10-10java進(jìn)制轉(zhuǎn)換工具類實(shí)現(xiàn)減少參數(shù)長度
這篇文章主要為大家介紹了java進(jìn)制轉(zhuǎn)換工具類實(shí)現(xiàn)減少參數(shù)長度示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02