在我們寫Java代碼時(shí),大部分情況下是不用關(guān)心你New的對(duì)象是否被釋放掉,或者什么時(shí)候被釋放掉。因?yàn)镴VM中有垃圾自動(dòng)回收機(jī)制。在之前的博客中我們聊過Objective-C中的MRC(手動(dòng)引用計(jì)數(shù))以及ARC(自動(dòng)引用計(jì)數(shù))的內(nèi)存管理方式,下方會(huì)對(duì)其進(jìn)行回顧。而目前的JVM的內(nèi)存回收機(jī)制則不是使用的引用計(jì)數(shù),而是主要使用的“復(fù)制式回收”和“自適應(yīng)回收”。
當(dāng)然除了上面是這兩種算法外,還有其他是算法,下方也將會(huì)對(duì)其進(jìn)行介紹。本篇博客,我們先簡(jiǎn)單聊一下JVM的區(qū)域劃分,然后在此基礎(chǔ)上介紹一下JVM的垃圾回收機(jī)制。
一、JVM內(nèi)存區(qū)域劃分簡(jiǎn)述
當(dāng)然本部分簡(jiǎn)單的聊一下JVM的內(nèi)存區(qū)域的劃分,為下方垃圾回收機(jī)制內(nèi)容的展開進(jìn)行鋪墊。當(dāng)然對(duì)JVM內(nèi)存區(qū)域劃分的內(nèi)容網(wǎng)上有好多詳細(xì)的內(nèi)容,請(qǐng)自行Google。
根據(jù)JVM內(nèi)存區(qū)域的劃分,簡(jiǎn)單的畫了下方的這個(gè)示意圖。區(qū)域主要分為兩大塊,一塊是堆區(qū)(Heap),我們所New出的對(duì)象都會(huì)在堆區(qū)進(jìn)行分配,在C語言中的malloc所分配的方法就是從Heap區(qū)獲取的。而垃圾回收器主要是對(duì)堆區(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ū)域,并對(duì)相應(yīng)的區(qū)域進(jìn)行整理。在堆區(qū)中,又根據(jù)對(duì)象內(nèi)存的存活時(shí)間或者對(duì)象大小,分為“年輕代”和“年老代”?!澳贻p代”中的對(duì)象是不穩(wěn)定的易產(chǎn)生垃圾,而“年老代”中的對(duì)象比較穩(wěn)定,不易產(chǎn)生垃圾。之所以將其分開,是分而治之,根據(jù)不同區(qū)域的內(nèi)存塊的