一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - JVM是如何和“垃圾”發(fā)生關(guān)系的

JVM是如何和“垃圾”發(fā)生關(guān)系的

2021-07-01 01:11碼上Java Java教程

在對(duì)象池中對(duì)象的引用層次,有的是很深的。比如一個(gè)調(diào)用非常頻繁的接口,生產(chǎn)對(duì)象的速度是非常可觀的。對(duì)象之間的關(guān)系,可以形容成一張網(wǎng)。雖然Java總是給人一種有使不完的內(nèi)存的感覺,但是對(duì)象也不能一直增加不減少啊,

JVM是如何和“垃圾”發(fā)生關(guān)系的

在開始之前,我們先回顧一下堆是個(gè)什么玩意,大家可能都知道,我們每天創(chuàng)建的Java對(duì)象幾乎都存放在堆上面,所以說堆是一個(gè)巨大的對(duì)象池一點(diǎn)都不過分,在這個(gè)對(duì)象池里面管理者數(shù)據(jù)巨大的對(duì)象實(shí)例。

在對(duì)象池中對(duì)象的引用層次,有的是很深的。比如一個(gè)調(diào)用非常頻繁的接口,生產(chǎn)對(duì)象的速度是非常可觀的。對(duì)象之間的關(guān)系,可以形容成一張網(wǎng)。雖然Java總是給人一種有使不完的內(nèi)存的感覺,但是對(duì)象也不能一直增加不減少啊,所以就必須有垃圾回收這個(gè)操作。

那么JVM如何發(fā)現(xiàn)垃圾的呢?

 

"垃圾回收"本文中簡(jiǎn)稱 GC

你還記得電視劇中的“誅九族""?

比如小憨批打了皇帝老兒一巴掌,把皇帝老兒打的鼻青臉腫滴,皇帝老兒非常生氣,他要下令誅小憨批的九族,以平心頭只恨。

哈哈哈嗝~ 小憨批完了~

那么我們看看在古代這個(gè)誅九族是具體操作的呢?首先需要追溯到共同的祖先(也就是小憨批家族的大哥大),再往下逐一細(xì)數(shù)和小憨批有關(guān)系的(小憨批真坑啊)。

其實(shí)發(fā)生在堆上的垃圾回收和這個(gè)“誅九族“的是相同思路,那么我們下面具體分析一下JVM是如何進(jìn)行GC的呢?

關(guān)于JVM的GC是不受程序控制的,當(dāng)滿足一定條件的時(shí)候就會(huì)主動(dòng)觸發(fā)。

當(dāng)發(fā)生GC的時(shí)候,對(duì)于一個(gè)對(duì)象來說,JVM總能夠找到引用它的祖先,當(dāng)找到最后的時(shí)候,JVM發(fā)現(xiàn)這家伙的有些祖先已經(jīng)玩完了,那么它們就會(huì)被JVM給干掉。

為什么還有沒有被干掉的祖先呢?因?yàn)檫@些躲過GC的祖先們,它們是GC Roots ,長得比較特殊嘛(下面介紹它們的樣子)。

當(dāng)從GC Roots 向下追溯、搜索,就會(huì)產(chǎn)生一個(gè)引用鏈。當(dāng)碰到有對(duì)象沒有任何一個(gè)GC Roots 產(chǎn)生關(guān)系的話,這個(gè)對(duì)象就會(huì)被無情的干掉。(一根繩上的螞蚱嘛)

來,我們畫個(gè)圖瞅瞅咋回事,如下圖所示,Object5、Object6、Object7,由于不能和 GC Root 產(chǎn)生關(guān)聯(lián),發(fā)生 GC 時(shí),就會(huì)被摧毀。

JVM是如何和“垃圾”發(fā)生關(guān)系的

其實(shí)所謂的垃圾回收就是圍繞著GC Roots 來的,但是同時(shí),GC Roots 也存在著很多內(nèi)存泄漏的根源,因?yàn)槠渌眯〉軌焊鶝]有這個(gè)權(quán)利。

你可能會(huì)產(chǎn)生疑問,那么什么樣的對(duì)象才會(huì)是GC Roots 呢?

這個(gè)不在于它是什么樣的對(duì)象,關(guān)鍵是它所處的位置(仔細(xì)品~)。

GC Roots 是什么

 

首先,GC Roots必須是一組必須活躍的引用。簡(jiǎn)單的講,就是程序接下來通過直接引用或間接引用,能夠被訪問到的潛在被使用的對(duì)象(咋感覺還是有點(diǎn)繞呢)。

GC Roots 是這樣子滴:

  1. Java線程中,當(dāng)前所有正在被調(diào)用的方法的引用類型參數(shù)、局部變量、臨時(shí)值等等。也就是與我們棧幀相關(guān)的各種引用。
  2. 所有當(dāng)前被加載的Java類。
  3. Java類的引用類型靜態(tài)變量。
  4. 運(yùn)行時(shí)常量池里的引用類型常量。
  5. JVM內(nèi)部數(shù)據(jù)結(jié)構(gòu)的一些引用,比如sun.jvm.hotspot.memory.Univers類。
  6. 用于同步的監(jiān)控對(duì)象。比如調(diào)用了對(duì)象的wait()方法。
  7. JNI handles,包括global handles 和 local handles。

以上GC Roots大致可以分為一下三大類。

  1. 活動(dòng)線程相關(guān)的各種引用。
  2. 類的靜態(tài)變量的引用。
  3. JNI引用。

最后我們需要注意的是,我們這里說的是活躍的引用,而不是對(duì)象,對(duì)象是不能作為GC Roots的。

整個(gè)GC過程中是找到那些活對(duì)象,并把剩余的空間都認(rèn)得為“無用”。而不是找到所有死掉的對(duì)象,并回收它們占用的空間。所有說,哪怕JVM的堆非常大,基于tracing的GC方式,回收速度也是跟快的。

總結(jié)

 

GC Roots 就是可達(dá)性分析法。還有一種叫作引用計(jì)數(shù)法的方式。下面我們簡(jiǎn)單介紹一下。

引用計(jì)數(shù)法:在Java中如果要操作對(duì)象,就必須先獲取該對(duì)象的引用,因此可以通過引用計(jì)數(shù)法來判斷一個(gè)對(duì)象是否可以被回收。在為一個(gè)對(duì)象添加一個(gè)引用時(shí),引用計(jì)數(shù)器就加1;為對(duì)象刪除一個(gè)引用時(shí),引用計(jì)數(shù)器就減1;如果一個(gè)對(duì)象的引用計(jì)數(shù)為0,則說明該對(duì)象沒有被引用,可以回收。

優(yōu)點(diǎn)是垃圾回收比較及時(shí),實(shí)時(shí)性比較高,只要對(duì)象計(jì)數(shù)器為 0,則可以直接進(jìn)行回收操作;而缺點(diǎn)是無法解決循環(huán)引用的問題。

因?yàn)榇嬖谘h(huán)引用這個(gè)致命的硬傷,沒有一個(gè)主流JVM是采用引用計(jì)數(shù)法來實(shí)現(xiàn) GC 的,所以你現(xiàn)在完全忘記引用計(jì)數(shù)這種方式了。

原文鏈接:https://mp.weixin.qq.com/s/t4q4lO79FSQMK0WllOcujg

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品视频人人做人人爱 | 欧美日韩国产成人综合在线影院 | 我和寂寞孕妇的性事 | 欧美一区二区三区四区五区六区 | 清清草在线视频 | 欧美成狂野欧美在线观看 | 天天狠天天透天干天天怕处 | 国产精品在线 | 成人在线视频观看 | 国产综合社区 | 亚洲精品国产在线网站 | 四虎精品在线观看 | 午夜欧美福利视频 | 久久香蕉电影 | 亚洲欧美日韩成人 | 狠狠色伊人亚洲综合网站色 | 寡妇快点好大好爽视频 | 国产综合视频在线 | 秋霞一级毛片 | 国产激情在线 | naruto堂同人本子汉化gg | spank日本网站脱裤子打屁股 | 亚洲视频免费在线看 | 99热这里只有精品国产在热久久 | 日本一本二本三区免费 | 亚洲另类第一页 | 日韩欧美一区二区在线 | 久久精品视频免费 | 国内精品 大秀视频 日韩精品 | 色多多在线视频 | 欧美男同video | 欧美午夜精品久久久久久黑人 | 国产成人综合精品一区 | 99精品国产自产在线观看 | 精品成人一区二区三区免费视频 | 高清国产精品久久 | 国产精品毛片va一区二区三区 | 亚洲美女aⅴ久久久91 | 欧美一级欧美一级高清 | 午夜精品久久久久久久99蜜桃 | 狠狠色综合久久婷婷色天使 |