摘要:年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對(duì)象。年老代在年輕代中經(jīng)歷了次垃圾回收后仍然存活的對(duì)象,就會(huì)被放到年老代中。什么情況下觸發(fā)垃圾回收由于對(duì)象進(jìn)行了分代處理,因此垃圾回收區(qū)域時(shí)間也不一樣。
[TOC]
與C/C++相比,java語(yǔ)言不需要程序員直接控制內(nèi)存回收,java程序的內(nèi)存分配和回收都是由JRE在后臺(tái)自動(dòng)進(jìn)行,JRE會(huì)負(fù)責(zé)回收那些不再使用的內(nèi)存,這種機(jī)制被稱為垃圾回收機(jī)制(Garbage Collection,GC):
主要負(fù)責(zé)兩件事情發(fā)現(xiàn)無(wú)用的對(duì)象
回收被無(wú)用對(duì)象占用的內(nèi)存空間,使之再次被程序使用(一般是在CPU空閑或者內(nèi)存不足時(shí))。
事實(shí)上,除了釋放沒(méi)用對(duì)象占用的內(nèi)存空間外,垃圾回收也可以清除內(nèi)存紀(jì)錄碎片(由于創(chuàng)建對(duì)象和垃圾回收器釋放丟棄對(duì)象所占的內(nèi)存空間)特點(diǎn)
垃圾回收機(jī)制的工作目標(biāo)是回收無(wú)用對(duì)象的內(nèi)存空間,==這些內(nèi)存空間都是jvm堆內(nèi)存(運(yùn)行時(shí)數(shù)據(jù)區(qū),用以保存類的實(shí)例,即對(duì)象)里的內(nèi)存空間==,不包含其它物力資源,比如數(shù)據(jù)庫(kù)連接、磁盤I/O等;
Java語(yǔ)言沒(méi)有顯式的提供分配內(nèi)存和刪除內(nèi)存的方法,一些開(kāi)發(fā)人員將引用對(duì)象設(shè)置為null或者調(diào)用System.gc()或者Runtime.getRuntime.gc()來(lái)釋放內(nèi)存(==后兩種方法僅是建議,慎重使用==);
垃圾回收不可預(yù)知,不同的jvm采用不同的垃圾回收機(jī)制和算法,有可能定時(shí)發(fā)生,有可能CPU空閑時(shí)發(fā)生,也有可能內(nèi)存耗盡時(shí)發(fā)生
分代垃圾回收 年輕代(Young Generation)所有新生成的對(duì)象首先都是放在年輕代的。
年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對(duì)象。
年輕代分三個(gè)區(qū)。一個(gè)Eden區(qū),兩個(gè)Survivor區(qū)(一般而言)。大部分對(duì)象在Eden區(qū)中生成。
當(dāng)Eden區(qū)滿時(shí),還存活的對(duì)象將被復(fù)制到Survivor區(qū)(兩個(gè)中的一個(gè))==(YGC,年輕代垃圾回收)==,當(dāng)這個(gè)Survivor區(qū)滿時(shí),此區(qū)的存活對(duì)象將被復(fù)制到另外一個(gè)Survivor區(qū),當(dāng)這個(gè)Survivor區(qū)也滿了的時(shí)候,從第一個(gè)Survivor區(qū)復(fù)制過(guò)來(lái)的并且此時(shí)還存活的對(duì)象,將被復(fù)制“年老區(qū)(Tenured)”。
需要注意,Survivor的兩個(gè)區(qū)是對(duì)稱的,沒(méi)先后關(guān)系,所以同一個(gè)區(qū)中可能同時(shí)存在從Eden復(fù)制過(guò)來(lái) 對(duì)象,和從前一個(gè)Survivor復(fù)制過(guò)來(lái)的對(duì)象,而復(fù)制到年老區(qū)的只有從第一個(gè)Survivor去過(guò)來(lái)的對(duì)象。而且,Survivor區(qū)總有一個(gè)是空的。
同時(shí),根據(jù)程序需要,Survivor區(qū)是可以配置為多個(gè)的(多于兩個(gè)),這樣可以增加對(duì)象在年輕代中的存在時(shí)間,減少被放到年老代的可能。年老代(Old Generation)
在年輕代中經(jīng)歷了N次垃圾回收后仍然存活的對(duì)象,就會(huì)被放到年老代中。因此,可以認(rèn)為年老代中存放的都是一些生命周期較長(zhǎng)的對(duì)象。
持久代(Permanent Generation)用于存放靜態(tài)文件,如今Java類、方法等。持久代對(duì)垃圾回收沒(méi)有顯著影響,但是有些應(yīng)用可能動(dòng)態(tài)生成或者調(diào)用一些class,例如Hibernate等,在這種時(shí)候需要設(shè)置一個(gè)比較大的持久代空間來(lái)存放這些運(yùn)行過(guò)程中新增的類。持久代大小通過(guò)-XX:MaxPermSize=
由于對(duì)象進(jìn)行了分代處理,因此垃圾回收區(qū)域、時(shí)間也不一樣。GC有兩種類型:Minor GC和Full GC。
Minor GC一般情況下,當(dāng)新對(duì)象生成,并且在Eden申請(qǐng)空間失敗時(shí),就會(huì)觸發(fā)Minor GC,對(duì)Eden區(qū)域進(jìn)行GC,清除非存活對(duì)象,并且把尚且存活的對(duì)象移動(dòng)到Survivor區(qū)。
然后整理Survivor的兩個(gè)區(qū)。
這種方式的GC是對(duì)年輕代的Eden區(qū)進(jìn)行,不會(huì)影響到年老代。因?yàn)榇蟛糠謱?duì)象都是從Eden區(qū)開(kāi)始的,同時(shí)Eden區(qū)不會(huì)分配的很大,所以Eden區(qū)的GC會(huì)頻繁進(jìn)行。因而,一般在這里需要使用速度快、效率高的算法,使Eden去能盡快空閑出來(lái)。
Full GC對(duì)整個(gè)堆進(jìn)行整理,包括Young、Tenured和Perm。Full GC因?yàn)樾枰獙?duì)整個(gè)對(duì)進(jìn)行回收,所以比Minor GC要慢,因此應(yīng)該盡可能減少Full GC的次數(shù)。
在對(duì)JVM調(diào)優(yōu)的過(guò)程中,很大一部分工作就是對(duì)于Full GC的調(diào)節(jié)。有如下原因可能導(dǎo)致Full GC:
年老代(Tenured)被寫滿
持久代(Perm)被寫滿
System.gc()被顯示調(diào)用
上一次GC之后Heap的各域分配策略動(dòng)態(tài)變化
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/72261.html
摘要:什么是線程餓死,什么是活鎖多線程中的忙循環(huán)是什么變量是什么變量和變量有什么不同類型變量提供什么保證能使得一個(gè)非原子操作變成原子操作嗎 JVM專題 showImg(https://segmentfault.com/img/remote/1460000019943435); (面試題+答案領(lǐng)取方式見(jiàn)個(gè)人主頁(yè)) Java 類加載過(guò)程? 描述一下 JVM 加載 Class 文件的原理機(jī)制? ...
摘要:內(nèi)存回收此時(shí),局部變量就沒(méi)有存在的必要了,因此可以釋放它們的內(nèi)存以供將來(lái)使用。局部變量會(huì)在它們離開(kāi)執(zhí)行環(huán)境時(shí)自動(dòng)被解除引用,如下面這個(gè)例子所示手工解除的引用由于局部變量在函數(shù)執(zhí)行完畢后就離開(kāi)了其執(zhí)行環(huán)境,因此無(wú)需我們顯式地去為它解除引用。 JavaScript 具有自動(dòng)垃圾收集機(jī)制(GC:Garbage Collecation),也就是說(shuō),執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過(guò)程中使用的內(nèi)存。而...
摘要:不能滿足被回收的條件,盡管調(diào)用也還是不能得到回收這就造成了內(nèi)存泄漏。種解決單例中的內(nèi)存泄漏將引用置為銷毀監(jiān)聽(tīng)使用弱引用將監(jiān)聽(tīng)器放入弱引用中從弱引用中取出回調(diào)通過(guò)第七小點(diǎn)就能完美的解決單例中回調(diào)引起的內(nèi)存泄漏。我們?yōu)槭裁匆獌?yōu)化內(nèi)存 showImg(https://user-gold-cdn.xitu.io/2019/5/12/16aac64e31d8c501); 在 Android 中我們寫的...
摘要:并發(fā)標(biāo)記清除垃圾回收器,使用多個(gè)線程來(lái)掃描堆內(nèi)存并標(biāo)記可被清除的對(duì)象,然后清除標(biāo)記的對(duì)象。垃圾回收器應(yīng)用于大的堆內(nèi)存空間。它將堆內(nèi)存空間劃分為不同的區(qū)域,對(duì)各個(gè)區(qū)域并行地做回收工作。它會(huì)通過(guò)把重復(fù)的值移動(dòng)到同一個(gè)數(shù)組來(lái)優(yōu)化堆內(nèi)存占用。 本文非原創(chuàng),翻譯自Types of Java Garbage Collectors在Java中為對(duì)象分配和釋放內(nèi)存空間都是由垃圾回收線程自動(dòng)執(zhí)行完成的。...
閱讀 3095·2021-10-13 09:40
閱讀 3945·2021-09-22 15:51
閱讀 1493·2021-09-22 15:48
閱讀 1060·2021-09-06 15:00
閱讀 1790·2019-08-30 15:43
閱讀 2355·2019-08-29 18:35
閱讀 1667·2019-08-29 16:18
閱讀 3612·2019-08-29 12:49