<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      JVM的內存區域劃分以及垃圾回收機制詳解

      在我們寫Java代碼時,大部分情況下是不用關心你New的對象是否被釋放掉,或者什么時候被釋放掉。因為JVM中有垃圾自動回收機制。在之前的博客中我們聊過Objective-C中的MRC(手動引用計數)以及ARC(自動引用計數)的內存管理方式,下方會對其進行回顧。而目前的JVM的內存回收機制則不是使用的引用計數,而是主要使用的“復制式回收”和“自適應回收”。

      當然除了上面是這兩種算法外,還有其他是算法,下方也將會對其進行介紹。本篇博客,我們先簡單聊一下JVM的區域劃分,然后在此基礎上介紹一下JVM的垃圾回收機制。

      一、JVM內存區域劃分簡述

      當然本部分簡單的聊一下JVM的內存區域的劃分,為下方垃圾回收機制內容的展開進行鋪墊。當然對JVM內存區域劃分的內容網上有好多詳細的內容,請自行Google。

      根據JVM內存區域的劃分,簡單的畫了下方的這個示意圖。區域主要分為兩大塊,一塊是堆區(Heap),我們所New出的對象都會在堆區進行分配,在C語言中的malloc所分配的方法就是從Heap區獲取的。而垃圾回收器主要是對堆區的內存進行回收的。

      而另一部分則是非堆區,非堆區主要包括用于編譯和保存本地代碼的“代碼緩存區(Code Cache)”、保存JVM自己的靜態數據的“永生代(Perm Gen)”、存放方法參數局部變量等引用以及記錄方法調用順序的“Java虛擬機棧(JVM Stack)”和“本地方法棧(Local Method Stack)”。

       

       

       

      垃圾回收器主要回收的是堆區中未使用的內存區域,并對相應的區域進行整理。在堆區中,又根據對象內存的存活時間或者對象大小,分為“年輕代”和“年老代”。“年輕代”中的對象是不穩定的易產生垃圾,而“年老代”中的對象比較穩定,不易產生垃圾。之所以將其分開,是分而治之,根據不同區域的內存塊的特點,采取不同的內存回收算法,從而提高堆區的垃圾回收的效率。下方會給出具體的介紹。

      二、常見的內存回收算法簡介

      上面我們簡單的了解的JVM中內存區域的劃分,接下來我們就來看一下幾種常見的內存回收算法。當然,下方所介紹的內存回收的算法不僅僅是JVM中所使用到的,我們還會回顧一下OC中的內存回收方式。下方主要包括“引用計數式回收”、“復制式回收”、“標記整理式回收”、“分代式回收”。

      1、引用計數式內存回收

      引用計數(Reference Count)式內存回收機制是Objective-C以及Swift語言中正在使用的內存回收機制,在之前的博客中我們也詳細的聊過引用計數式的內存回收。只要有引用,那么引用計數就加1。當引用計數為0時,該塊內存就會被回收。當然這中內存清理方式容易形成“引用循環”。

      Objective-C的引用計數中循環引用而造成內存泄露的問題,可以將變量聲明成weak或者strong類型。也就是說我們可以將引用定義為“強引用”或者“弱引用”。當出現“強引用循環”時,我們將其中的一個引用設置為weak類型即可,然后這種強引用循環就被打破了,也就不會造成“內存泄露”的問題。關于“引用計數式內存回收”的更多以及更詳細的內容,請參考之前發布的關于OC內容的相關博客。

      為了更清晰的了解引用計數的工作方式,就簡單的畫了下方這個圖。在左邊的棧中的a、b、c三個引用分別指向堆中的不同區域塊。在堆中的內存區域塊中,該區域有一個強引用時,其retainCount就會加1。而在弱引用時,就retainCount就不會加1。

      我們先來看看a引用的第1塊內存區域,因為該內存塊只有a在強引用,所以retainCount=1,當a不在引用該內存區域時,retainCount=0,該內存會理解被回收的。這種情況下是不會造成內存泄露的。

      我們再來看看b指向的內存區域2。b和內存塊3都強引用了內存塊2,所以2的retainCount=2。而內存塊2也強引用了內存塊3,所以3的retainCount=1。所以b指向的這塊內存區域就存在“強引用循環”,因為當b不再指向這塊內存區域時,rc=2就會變為rc=1。因為retainCount不為零,所以這2塊內存區域是不會被釋放的,2不會被釋放,那么自然而然的3塊內存區域也不會被釋放,但是這塊內存區域有不會再被使用到了,所以就會造成“內存泄露”的情況。如果這兩塊內存區域特別大,那么我們可想而知,后果是比較嚴重的。

      像c引用的這塊情況,就不會引起“強引用循環”,因為其中的一個引用鏈是是弱引用的。當c不在引用第4塊內存時,rc由1變為零,那么該塊區域就會被立即釋放。而內存塊4被釋放后,內存塊5的rc由1變為0,內存塊5也會被釋放掉。這種情況下是不會引起內存泄露的。而在Objective-C中正是采用的這種方式來回收內存的,當然了,在OC中除了“強引用”和“弱引用”外,還有自動釋放池。也就是說,Autorealease類型的引用,讓retainCount = 0時,不會被立即釋放掉,而是在出自動釋放池時才會被釋放掉,在此就不做過多贅述了。

       

       

      2、復制式內存回收

      聊完引用計數回收,我們知道引用計數容易引起“循環引用”的問題,為了解決“循環引用”引起的內存泄露問題,OC中引入和“強引用”和“弱引用”的概念。接下來我們在看看復制式內存回收機制,在該機制中是不需要關心“循環引用”的問題的。簡單的說,復制式回收其核心就是“復制”,但前提是有條件復制。在垃圾回收時,將“活對象”復制到另一塊空白的堆區,然后將之前的區域一并清除。“活對象”就是指沿著對象的引用鏈可以到“棧”上的對象。當然在將活對象復制到新的“堆區”后,也要將棧區的引用進行修改。

      下方就是我們畫的復制式回收的簡圖,主要將堆分為兩大部分,在進行垃圾回收時,會將一個堆上的活對象復制到另一個堆上。下方堆1區是目前正在使用的區塊,堆2區則是空閑區。而在堆1區中未被標記的那些內存塊,也就是2、3是要被回收的垃圾對象。而1、4、5是要被復制的“活對象”。因為沿著棧上的a可到達區塊1、沿著c可到達區塊4、5。而區塊2和3雖然有引用,但是不是來自非堆區,也就是2和3的引用都是來自堆區的引用,所以是要被回收的對象。

       

       

       

      找到了活對象后,接下來要做的就是將活對象進行復制,將其復制到堆2區。當然,復制到堆2區的對象間的內存地址是連續的,如果要分配新的內存空間的話,直接從堆空閑的一段分配即可。這樣在分配內存空間時的效率是比較高的。對象復制后,要修改來自“非堆區”的引用地址。如下所示。

       

       

       

      復制完畢后,我們直接將堆2區的中的所有內存空間進行回收即可,下方就是復制回收后的最終結果。下方的堆1區清空后,可以接收復制過來的對象了。當對堆2區進行垃圾回收時,會把堆2區的活對象拷貝到堆1區上。

      從該實例中我們可以看出當內存垃圾特別多的時候“復制式”垃圾回收的效率還是比較高的,因為復制的對象比較少,清除時直接將舊的堆空間進行清理即可。但是,當垃圾比較少的時候,這種方式會復制大量的活對象,效率還是比較低的。這種方式也會將堆的存儲空間進行分半。也就是說,總有一半是空閑的,堆空間的利用率不高。

       

       

       

      3、標記-壓縮回收算法

      從上述“復制式”垃圾回收過程中,我們知道,垃圾多時其效率比較高,而垃圾少時,其工作方式效率是比較低的。那么,接下來,我們來介紹另一種標記-壓縮回收算法,這種算法在垃圾少時的工作效率比較高,而垃圾多的情況下,工作效率反而不高,這就與“復制式”形成了互補。下方我們將會對標記-壓縮回收算法進行介紹。

      標記-壓縮的第一部就是標記,需要將堆區中的“活對象”進行標記。上面的內容我們已經聊了什么是“活對象”,在此就不做過多贅述了。由“活對象”的特征我們可以看出,下方的活對象是內存區域1和3,所以我們將其進行標記。

       

       

       

      標記完成后,我們就開始進行壓縮了,將活對象壓縮到“堆區”的一段,然后將剩余的部分進行清除。下方就是將1和3這兩個活對象進行了壓縮。壓縮后,將下方的空間進行Clean。也就是說Clean的部分,就可以分配新的對象了。

       

       

      下方截圖是標記-壓縮清理后的狀態。標記-壓縮式垃圾回收可充分利用堆區的空間,當垃圾比較少時,這種處理方式效率還是比較高的,如果垃圾太多碎片化嚴重時,移動的“活對象”較多,效率比較低。這種方式可以與“復制式”結合使用,根據當前堆區的垃圾狀態來選擇哪種回收方式。正好與“復制式”形成優勢互補。將“復制式”、“標記-壓縮式”的回收方式進行整合的算法,就是“分代式”垃圾回收機制,下方會詳細介紹到。

       

       

       

      4、分代式垃圾回收

      分代”即根據對象易產生垃圾的狀態或者對象的大小將其分為不同的代,可分為“年輕代”、“年老代”和“永久代”。“永久代”不在堆中,再次先不做討論。根據分代垃圾回收的特點,畫了下方的簡圖。

      在堆中,主要把區域分為“年輕代”、“年老代”。位于“年輕代”的對象內存創建的時間不長,更新比較快,易產生“內存垃圾”,所以“年輕代”的垃圾回收使用“復制式”回收方式效率比較高。“年輕代”又可分為兩個區,一個是Eden Space(伊甸園)和Survivor Sprace(幸存者區)。Eden Space去主要存放那些初次被創建的對象,而Survivor Sprace存放的是從Eden Space幸存下來的“活對象”。在Survivor Sprace(幸存者區)中又分為form和to兩塊,用于相互復制對象來進行垃圾清理。

      而“年老代”中存放的是一些“大對象”以及從Survivor Sprace中存活下來的“對象”,一般到“年老代”的對象比較穩定,產生垃圾較少,針對這種情況,使用“標記-壓縮”式回收效率比較高。“分代垃圾回收”主要是分而治之,根據不同對象的特點將其分類,根據分類的特點來具體選擇合適的垃圾回收方案。

       

       

       

      三、分代式垃圾回收的具體工作原理

      當然在JVM具體的垃圾回收時,根據線程分可分為使用單個線程回收的“串行垃圾回收”,使用多個線程回收的“并行垃圾回收”。根據程序的掛起狀態,又可分為“獨占式回收”和“并發式回收”。當然之前也多次聊過“并行”與“并發”絕對不是一個概念,切不可將其混淆。本篇博客就不對上述這些方式進行詳述了,感興趣的,請自行Google。

      下面我們來看一下“分代式垃圾回收”的具體工作原理的完整步驟,來直觀的感受一下“分代式”的垃圾回收的執行方式。

      1、垃圾回收前

      下圖是等待“分代垃圾回收”的簡圖,從下圖中,我們可以看出在堆中有些已分配的對象內存并沒有被棧上引用,這些就是要被回收的對象。我們可以看出,下方的堆,整體上分為“年輕代”和“年老代”,而年輕代,有可細分為Eden SpaceFrom以及To三個區域。關于每個區域的作用,在上面介紹“分代垃圾回收”時,我們已經介紹過了,所以在此部分我們不做詳細介紹了。

       

       

       

      2、分代垃圾回收

      下圖是對上述堆控件的垃圾回收過程。因為我們有上圖可以看出,To區域是空白區,可以接受被復制的對象。由于“年輕代”易產生內存垃圾,所以采用“復制式”內存回收的方式。我們將Eden Space和From兩個堆區塊中的“活對象”拷貝到To區。拷貝的同時,我們也要修改被拷貝內存的棧引用地址。而對From或者Eden區域的“大對象”存儲空間直接將其復制到“年老代”。因為“大對象”在From與To區多次復制的效率比較低,直接將其加入到“年老代”中以提高回收效率。

      對于“年老代”的垃圾回收,就采用“標記-壓縮”式垃圾回收。首先,先將活對象進行“標記”。

       

       

       

      3、垃圾回收后的結果

      下方就是“分代”垃圾回收后的具體結果。從下方簡圖中,我們可以看出,Eden Space和From中的活對象都被復制到了To區,而“年老代”的堆區的存儲空間也變化不少。而且在“年老代”中多出了從From區復制過來的大對象。具體如下所示。

       

      posted @ 2020-03-05 18:19  流氓大隊長  閱讀(725)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品国产亚洲区久久露脸| 午夜色无码大片在线观看免费| 岳阳市| 中文字幕av日韩有码| 性奴sm虐辱暴力视频网站| 欧美牲交a欧美在线| 无码av永久免费专区麻豆| 亚洲一区二区三区激情视频 | 男女猛烈激情xx00免费视频| 亚洲综合中文字幕第一页| 精品人妻少妇一区二区三区在线| 热久在线免费观看视频| 午夜福利免费区在线观看| 亚洲中文字幕日产无码成人片| 久青草国产在视频在线观看| 国产精品国产三级国产午| 亚洲VA久久久噜噜噜久久无码| 色爱综合激情五月激情| 精品国产伦理国产无遮挡| 久久国内精品自在自线91| 国产精品久久久一区二区三区| 91亚洲国产成人精品福利| 人人做人人澡人人人爽| 在线无码午夜福利高潮视频| 国产日韩综合av在线| 久久一日本道色综合久久| 高清破外女出血AV毛片| 在线涩涩免费观看国产精品| www夜插内射视频网站| 中文字幕一区二区精品区 | 中文字幕人妻中出制服诱惑| 日韩有码中文字幕国产| 奶头好大揉着好爽视频| 少妇高潮太爽了在线视频| 少妇被粗大的猛烈xx动态图 | 久久夜色精品国产亚洲av| 国产成人精品无码专区| 亚洲自拍偷拍一区二区三区| 亚洲第一极品精品无码久久| 奶头又大又白喷奶水av| 免费无遮挡无码视频网站|