JVM+GC解析(題目1)
1、JVM垃圾回收的時(shí)候如何確定垃圾?是否知道什么是GC Roots?
GC Root如何確定?那些對(duì)象可以作為GC Root?
1.1、什么是垃圾?
簡(jiǎn)單說(shuō)就是內(nèi)存中已經(jīng)不再被使用到的空間就是垃圾
比如一個(gè)對(duì)象指向NULL了,慢慢得就會(huì)被回收了
1.2、要進(jìn)行垃圾回收,如何判斷一個(gè)對(duì)象是否可以被回收?
1.2.1、引用計(jì)數(shù)法
給對(duì)象添加一個(gè)引用計(jì)數(shù)器
每當(dāng)有一個(gè)地方引用它,計(jì)數(shù)器值加1
每當(dāng)有一個(gè)引用失效時(shí),計(jì)數(shù)器值減1
任何時(shí)刻計(jì)數(shù)器值為0的對(duì)象就是不可能再被使用的,那么這個(gè)對(duì)象就是可回收對(duì)象。
但是主流JVM中并沒(méi)有選用這個(gè)算法,因?yàn)檫@種算法很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題。
1.2.2、枚舉根節(jié)點(diǎn)做 可達(dá)性分析(根搜索路徑)
為了解決引用計(jì)數(shù)器的循環(huán)引用問(wèn)題,Java使用了可達(dá)性分析的方法。
跟蹤 (Tracing)
- 復(fù)制(Copying)
- 標(biāo)記清除(Mark-Sweep)
- 標(biāo)記壓縮(Mark-Compact)(Mark-Sweep-Compact)
GC引用遍歷
對(duì)象B就是對(duì)象可達(dá),對(duì)象C基本上就稱(chēng)為對(duì)象不可達(dá)
所謂“GC Roots”或者說(shuō)Tracing GC的“根集合”就是一組必須活躍的引用。
基本思路就是通過(guò)一系列名為“GC Roots”的對(duì)象作為起始點(diǎn),從這個(gè)名為“GC Roots”的對(duì)象開(kāi)始向下搜索,如果一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連時(shí),則說(shuō)明這個(gè)對(duì)象不可用(例如上圖對(duì)象C)。也即給定一個(gè)集合的引用作為根出發(fā),通過(guò)引用關(guān)系遍歷對(duì)象圖,能被遍歷到的(可達(dá)到的)對(duì)象就被判定為存活;沒(méi)有遍歷到的(不可達(dá)的)就被判定為死亡。
簡(jiǎn)單理解:人為設(shè)置一些人為貴族,凡是和這些貴族沒(méi)有血緣關(guān)系的人則逐出城外。
那么問(wèn)題就來(lái)到了,到底哪些對(duì)象應(yīng)該被設(shè)置為GC Roots”對(duì)象呢?
- 虛擬機(jī)棧(棧幀中的局部變量區(qū),也叫局部變量表)中引用的對(duì)象。
- 方法區(qū)中的類(lèi)靜態(tài)屬性引用的對(duì)象。
- 方法區(qū)中的常量引用的對(duì)象。
本地方法棧中JNI(Native方法)引用的對(duì)象。
