這篇文章將為大家詳細(xì)講解有關(guān)JVM調(diào)優(yōu)中垃圾回收面臨的問題是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)湯原免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上1000家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
如何區(qū)分垃圾
上面說(shuō)到的“引用計(jì)數(shù)”法,通過統(tǒng)計(jì)控制生成對(duì)象和刪除對(duì)象時(shí)的引用數(shù)來(lái)判斷。垃圾回收程序收集計(jì)數(shù)為0的對(duì)象即可。但是這種方法無(wú)法解決循環(huán)引用。所以,后來(lái)實(shí)現(xiàn)的垃圾判斷算法中,都是從程序運(yùn)行的根節(jié)點(diǎn)出發(fā),遍歷整個(gè)對(duì)象引用,查找存活的對(duì)象。那么在這種方式的實(shí)現(xiàn)中,垃圾回收從哪兒開始的呢?即,從哪兒開始查找哪些對(duì)象是正在被當(dāng)前系統(tǒng)使用的。上面分析的堆和棧的區(qū)別,其中棧是真正進(jìn)行程序執(zhí)行地方,所以要獲取哪些對(duì)象正在被使用,則需要從Java棧開始。同時(shí),一個(gè)棧是與一個(gè)線程對(duì)應(yīng)的,因此,如果有多個(gè)線程的話,則必須對(duì)這些線程對(duì)應(yīng)的所有的棧進(jìn)行檢查。
同時(shí),除了棧外,還有系統(tǒng)運(yùn)行時(shí)的寄存器等,也是存儲(chǔ)程序運(yùn)行數(shù)據(jù)的。這樣,以?;蚣拇嫫髦械囊脼槠瘘c(diǎn),我們可以找到堆中的對(duì)象,又從這些對(duì)象找到對(duì)堆中其他對(duì)象的引用,這種引用逐步擴(kuò)展,最終以null引用或者基本類型結(jié)束,這樣就形成了一顆以Java棧中引用所對(duì)應(yīng)的對(duì)象為根節(jié)點(diǎn)的一顆對(duì)象樹,如果棧中有多個(gè)引用,則最終會(huì)形成多顆對(duì)象樹。在這些對(duì)象樹上的對(duì)象,都是當(dāng)前系統(tǒng)運(yùn)行所需要的對(duì)象,不能被垃圾回收。而其他剩余對(duì)象,則可以視為無(wú)法被引用到的對(duì)象,可以被當(dāng)做垃圾進(jìn)行回收。
因此,垃圾回收的起點(diǎn)是一些根對(duì)象(java棧, 靜態(tài)變量, 寄存器...)。而最簡(jiǎn)單的Java棧就是Java程序執(zhí)行的main函數(shù)。這種回收方式,也是上面提到的“標(biāo)記-清除”的回收方式。
如何處理碎片
由于不同Java對(duì)象存活時(shí)間是不一定的,因此,在程序運(yùn)行一段時(shí)間以后,如果不進(jìn)行內(nèi)存整理,就會(huì)出現(xiàn)零散的內(nèi)存碎片。碎片最直接的問題就是會(huì)導(dǎo)致無(wú)法分配大塊的內(nèi)存空間,以及程序運(yùn)行效率降低。所以,在上面提到的基本垃圾回收算法中,“復(fù)制”方式和“標(biāo)記-整理”方式,都可以解決碎片的問題。
如何解決同時(shí)存在的對(duì)象創(chuàng)建和對(duì)象回收問題
垃圾回收線程是回收內(nèi)存的,而程序運(yùn)行線程則是消耗(或分配)內(nèi)存的,一個(gè)回收內(nèi)存,一個(gè)分配內(nèi)存,從這點(diǎn)看,兩者是矛盾的。因此,在現(xiàn)有的垃圾回收方式中,要進(jìn)行垃圾回收前,一般都需要暫停整個(gè)應(yīng)用(即:暫停內(nèi)存的分配),然后進(jìn)行垃圾回收,回收完成后再繼續(xù)應(yīng)用。這種實(shí)現(xiàn)方式是最直接,而且最有效的解決二者矛盾的方式。
但是這種方式有一個(gè)很明顯的弊端,就是當(dāng)堆空間持續(xù)增大時(shí),垃圾回收的時(shí)間也將會(huì)相應(yīng)的持續(xù)增大,對(duì)應(yīng)應(yīng)用暫停的時(shí)間也會(huì)相應(yīng)的增大。一些對(duì)相應(yīng)時(shí)間要求很高的應(yīng)用,比如***暫停時(shí)間要求是幾百毫秒,那么當(dāng)堆空間大于幾個(gè)G時(shí),就很有可能超過這個(gè)限制,在這種情況下,垃圾回收將會(huì)成為系統(tǒng)運(yùn)行的一個(gè)瓶頸。為解決這種矛盾,有了并發(fā)垃圾回收算法,使用這種算法,垃圾回收線程與程序運(yùn)行線程同時(shí)運(yùn)行。在這種方式下,解決了暫停的問題,但是因?yàn)樾枰谛律蓪?duì)象的同時(shí)又要回收對(duì)象,算法復(fù)雜性會(huì)大大增加,系統(tǒng)的處理能力也會(huì)相應(yīng)降低,同時(shí),“碎片”問題將會(huì)比較難解決。
關(guān)于JVM調(diào)優(yōu)中垃圾回收面臨的問題是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。