在我們寫Java代碼時,大部分情況下是不用關(guān)心你New的對象是否被釋放掉,或者什么時候被釋放掉。因為JVM中有垃圾自動回收機(jī)制。在之前的博客中我們聊過Objective-C中的MRC(手動引用計數(shù))以及ARC(自動引用計數(shù))的內(nèi)存管理方式,下方會對其進(jìn)行回顧。而目前的JVM的內(nèi)存回收機(jī)制則不是使用的引用計數(shù),而是主要使用的“復(fù)制式回收”和“自適應(yīng)回收”。
當(dāng)然除了上面是這兩種算法外,還有其他是算法,下方也將會對其進(jìn)行介紹。本篇博客,我們先簡單聊一下JVM的區(qū)域劃分,然后在此基礎(chǔ)上介紹一下JVM的垃圾回收機(jī)制。
一、JVM內(nèi)存區(qū)域劃分簡述
當(dāng)然本部分簡單的聊一下JVM的內(nèi)存區(qū)域的劃分,為下方垃圾回收機(jī)制內(nèi)容的展開進(jìn)行鋪墊。當(dāng)然對JVM內(nèi)存區(qū)域劃分的內(nèi)容網(wǎng)上有好多詳細(xì)的內(nèi)容,請自行Google。
根據(jù)JVM內(nèi)存區(qū)域的劃分,簡單的畫了下方的這個示意圖。區(qū)域主要分為兩大塊,一塊是堆區(qū)(Heap),我們所New出的對象都會在堆區(qū)進(jìn)行分配,在C語言中的malloc所分配的方法就是從Heap區(qū)獲取的。而垃圾回收器主要是對堆區(qū)的內(nèi)存進(jìn)行回收的。
而另一部分則是非堆區(qū),非堆區(qū)主要包括用于編譯和保存本地代碼的“代碼緩存區(qū)(Code Cache)”、保存JVM自己的靜態(tài)數(shù)據(jù)的“永生代(Perm Gen)”、存放方法參數(shù)局部變量等引用以及記錄方法調(diào)用順序的“Java虛擬機(jī)棧(JVM Stack)”和“本地方法棧(Local Method Stack)”。
垃圾回收器主要回收的是堆區(qū)中未使用的內(nèi)存區(qū)域,并對相應(yīng)的區(qū)域進(jìn)行整理。在堆區(qū)中,又根據(jù)對象內(nèi)存的存活時間或者對象大小,分為“年輕代”和“年老代”?!澳贻p代”中的對象是不穩(wěn)定的易產(chǎn)生垃圾,而“年老代”中的對象比較穩(wěn)定,不易產(chǎn)生垃圾。之所以將其分開,是分而治之,根據(jù)不同區(qū)域的內(nèi)存塊的