java知识点8——垃圾回收原理和算法、通用的分代垃圾回收机制、 JVM调优和Full GC、开发中容易造成内存泄露的操作
垃圾回收原理和算法
內(nèi)存管理
Java的內(nèi)存管理很大程度指的就是對(duì)象的管理,其中包括對(duì)象空間的分配和釋放。
對(duì)象空間的分配:使用new關(guān)鍵字創(chuàng)建對(duì)象即可
對(duì)象空間的釋放:將對(duì)象賦值null即可
垃圾回收器將負(fù)責(zé)回收所有”不可達(dá)”對(duì)象的內(nèi)存空間
垃圾回收過(guò)程
任何一種垃圾回收算法一般要做兩件基本事情:
1. 發(fā)現(xiàn)無(wú)用的對(duì)象
2. 回收無(wú)用對(duì)象占用的內(nèi)存空間。
垃圾回收相關(guān)算法
? ? ? ? 1. 引用計(jì)數(shù)法
? ? ? ? ? ?堆中每個(gè)對(duì)象都有一個(gè)引用計(jì)數(shù)。被引用一次,計(jì)數(shù)加1. 被引用變量值變?yōu)閚ull,則計(jì)數(shù)減1,直到計(jì)數(shù)為0,則表示變成無(wú)用對(duì)象。優(yōu)點(diǎn)是算法簡(jiǎn)單,缺點(diǎn)是“循環(huán)引用的無(wú)用對(duì)象”無(wú)法別識(shí)別。
? ? ? ?2. 引用可達(dá)法(根搜索算法)
通用的分代垃圾回收機(jī)制
? ? ? ?分代垃圾回收機(jī)制,是基于這樣一個(gè)事實(shí):不同的對(duì)象的生命周期是不一樣的。因此,不同生命周期的對(duì)象可以采取不同的回收算法,以便提高回收效率。我們將對(duì)象分為三種狀態(tài):年輕代、年老代、持久代。JVM將堆內(nèi)存劃分為 Eden、Survivor 和 Tenured/Old 空間。
? ? ? ?1. 年輕代
? ? ? ? ?所有新生成的對(duì)象首先都是放在Eden區(qū)。 年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對(duì)象,對(duì)應(yīng)的是Minor GC,每次 Minor GC 會(huì)清理年輕代的內(nèi)存,算法采用效率較高的復(fù)制算法,頻繁的操作,但是會(huì)浪費(fèi)內(nèi)存空間。當(dāng)“年輕代”區(qū)域存放滿對(duì)象后,就將對(duì)象存放到年老代區(qū)域。
? ? ? ? 2. 年老代
? ? ? ? 在年輕代中經(jīng)歷了N(默認(rèn)15)次垃圾回收后仍然存活的對(duì)象,就會(huì)被放到年老代中。因此,可以認(rèn)為年老代中存放的都是一些生命周期較長(zhǎng)的對(duì)象。年老代對(duì)象越來(lái)越多,我們就需要啟動(dòng)Major GC和Full GC(全量回收),來(lái)一次大掃除,全面清理年輕代區(qū)域和年老代區(qū)域。
3. 持久代
? ? ? ?用于存放靜態(tài)文件,如Java類、方法等。持久代對(duì)垃圾回收沒(méi)有顯著影響
?
? ? ? ? Minor GC:
用于清理年輕代區(qū)域。Eden區(qū)滿了就會(huì)觸發(fā)一次Minor GC。清理無(wú)用對(duì)象,將有用對(duì)象復(fù)制到“Survivor1”、“Survivor2”區(qū)中(這兩個(gè)區(qū),大小空間也相同,同一時(shí)刻Survivor1和Survivor2只有一個(gè)在用,一個(gè)為空)
Major GC:
用于清理老年代區(qū)域。
Full GC:
用于清理年輕代、年老代區(qū)域。 成本較高,會(huì)對(duì)系統(tǒng)性能產(chǎn)生影響。
垃圾回收過(guò)程:
? ? 1、新創(chuàng)建的對(duì)象,絕大多數(shù)都會(huì)存儲(chǔ)在Eden中,
? ? 2、當(dāng)Eden滿了(達(dá)到一定比例)不能創(chuàng)建新對(duì)象,則觸發(fā)垃圾回收(GC),將無(wú)用對(duì)象清理掉,
???????????然后剩余對(duì)象復(fù)制到某個(gè)Survivor中,如S1,同時(shí)清空Eden區(qū)
? ? 3、當(dāng)Eden區(qū)再次滿了,會(huì)將S1中的不能清空的對(duì)象存到另外一個(gè)Survivor中,如S2,
? ? ? ? ??同時(shí)將Eden區(qū)中的不能清空的對(duì)象,也復(fù)制到S2中,保證Eden和S1,均被清空。
? ? 4、重復(fù)多次(默認(rèn)15次)Survivor中沒(méi)有被清理的對(duì)象,則會(huì)復(fù)制到老年代Old(Tenured)區(qū)中,
? ? 5、當(dāng)Old區(qū)滿了,則會(huì)觸發(fā)一個(gè)一次完整地垃圾回收(FullGC),之前新生代的垃圾回收稱為(minorGC)
?JVM調(diào)優(yōu)和Full GC
在對(duì)JVM調(diào)優(yōu)的過(guò)程中,很大一部分工作就是對(duì)于Full GC的調(diào)節(jié)。有如下原因可能導(dǎo)致Full GC:
1.年老代(Tenured)被寫滿
2.持久代(Perm)被寫滿
3.System.gc()被顯式調(diào)用(程序建議GC啟動(dòng),不是調(diào)用GC)
4.上一次GC之后Heap的各域分配策略動(dòng)態(tài)變化
開(kāi)發(fā)中容易造成內(nèi)存泄露的操作
注:在實(shí)際開(kāi)發(fā)中,內(nèi)存泄露經(jīng)常會(huì)造成系統(tǒng)的崩潰。
? ? ? ?1. 程序員無(wú)權(quán)調(diào)用垃圾回收器。
2. 程序員可以調(diào)用System.gc(),該方法只是通知JVM,并不是運(yùn)行垃圾回收器。盡量少用,會(huì)申請(qǐng)啟動(dòng)Full GC,成本高,影響系統(tǒng)性能。
3. finalize方法,是Java提供給程序員用來(lái)釋放對(duì)象或資源的方法,但是盡量少用。
總結(jié)
以上是生活随笔為你收集整理的java知识点8——垃圾回收原理和算法、通用的分代垃圾回收机制、 JVM调优和Full GC、开发中容易造成内存泄露的操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java知识点7——面向过程和面向对象、
- 下一篇: java的知识点11——面向对象的三大特