国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

中國十大軟件上市公司排名seo從零開始到精通200講解

中國十大軟件上市公司排名,seo從零開始到精通200講解,技術(shù)先進的網(wǎng)站建設(shè),網(wǎng)站欄目頁怎么做文章目錄 一. JVM內(nèi)存劃分二. 類加載機制1. 類加載過程2. 雙親委派模型 三. GC垃圾回收機制1. 找到需要回收的內(nèi)存1.1 哪些內(nèi)存需要回收?1.2 基于引用計數(shù)找垃圾(Java不采取該方案)1.3 基于可達性分析找垃圾(Java采取方案) 2. 垃圾回收算法2.1 標(biāo)記-清除算法2.2 標(biāo)記…

文章目錄

  • 一. JVM內(nèi)存劃分
  • 二. 類加載機制
    • 1. 類加載過程
    • 2. 雙親委派模型
  • 三. GC垃圾回收機制
    • 1. 找到需要回收的內(nèi)存
      • 1.1 哪些內(nèi)存需要回收?
      • 1.2 基于引用計數(shù)找垃圾(Java不采取該方案)
      • 1.3 基于可達性分析找垃圾(Java采取方案)
    • 2. 垃圾回收算法
      • 2.1 標(biāo)記-清除算法
      • 2.2 標(biāo)記-復(fù)制算法
      • 2.3 標(biāo)記-整理算法
      • 2.4 分代回收

一. JVM內(nèi)存劃分

JVM 其實是一個 Java 進程,該進程會從操作系統(tǒng)中申請一大塊內(nèi)存區(qū)域,提供給 Java 代碼使用,申請的內(nèi)存區(qū)域會進一步做出劃分,給出不同的用途。

其中最核心的是棧,堆,方法區(qū)這幾個區(qū)域:

  1. 堆,用來放置 new 出來的對象,類成員變量。
  2. 棧,維護方法之間的調(diào)用關(guān)系,放置局部變量。
  3. 方法區(qū)(舊)/元數(shù)據(jù)區(qū)(新):放的是類加載之后的類對象(.class文件),靜態(tài)變量,二進制指令(方法)。

細分下來 JVM 的內(nèi)存區(qū)域包括以下幾個:程序計數(shù)器,棧,堆,方法區(qū),圖中的元數(shù)據(jù)區(qū)可以理解為方法區(qū)。
img

🍂程序計數(shù)器:內(nèi)存最小的一塊區(qū)域,保存了下一條要執(zhí)行的指令(字節(jié)碼)的地址,每個線程都有一份

🍂:儲存局部變量與方法之間的調(diào)用信息,每一個線程都有一份,但要注意“棧是線程私有的”這種說法是不準(zhǔn)確的,私有的意思是我的你是用不了的,但實際上,一個線程棧上的內(nèi)容,是可以被另一個線程使用到的。

img

棧在 JVM 區(qū)域劃分中分為兩種,一種是 Java 虛擬機棧,另外一種是本地方法棧,這兩種棧功能非常類似,當(dāng)方法被調(diào)用時,都會同步創(chuàng)建棧幀來存儲局部變量表、操作數(shù)棧、動態(tài)連接、方法出口等信息。

只不過虛擬機棧是為虛擬機執(zhí)行 Java 方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是給 JVM 內(nèi)部的本地(Native)方法服務(wù)的(JVM 內(nèi)部通過 C++ 代碼實現(xiàn)的方法)。
img

🍂:儲存對象以及對象的成員變量,一個 JVM 進程只有一個,多個線程共用一個堆,是內(nèi)存中空間最大的區(qū)域,Java 堆是垃圾回收器管理的內(nèi)存區(qū)域,后文介紹 GC 的時候細說。

🍂方法區(qū): JDK 1.8 開始,叫做元數(shù)據(jù)區(qū),存儲了類對象,常量池,靜態(tài)成員變量,即時編譯器編譯后的代碼緩存等數(shù)據(jù);所謂的“類對象”,就是被static修飾的變量或方法就成了類屬性,.java文件會被編譯成.class文件,.class會被加載到內(nèi)存中,也就被 JVM 構(gòu)造成類對象了,類對象描述了類的信息,如類名,類有哪些成員,每個成員叫什么名字,權(quán)限是什么,方法名等;同樣一個 JVM 進程只有一個元數(shù)據(jù)區(qū),多個線程共用一塊元數(shù)據(jù)區(qū)內(nèi)存。

img

要注意 JVM 的線程和操作系統(tǒng)的線程是一對一的關(guān)系,每次在 Java 代碼中創(chuàng)建的線程,必然會在系統(tǒng)中有一個對應(yīng)的線程。

二. 類加載機制

1. 類加載過程

類加載就是把.java文件使用javac編譯為.class文件,從文件(硬盤)被加載到內(nèi)存中(元數(shù)據(jù)區(qū)),得到類對象的過程。(程序要想運行,就需要把依賴的“指令和數(shù)據(jù)”加載到內(nèi)存中)。

img
這個圖片所示的類加載過程來自官方文檔,類加載包括三個步驟:LoadingLinkingInitialization
官方文檔:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html
img

下面就來了解一下這三步是在干什么:

第一步,加載Loading),找到對應(yīng)的.class文件,打開并讀取文件到內(nèi)存中,同時通過解析文件初步生成一個代表這個類的 java.lang.Class 對象。

第二步,連接Linking),作用是建立多個實體之間的聯(lián)系,該過程有包含三個小過程:

  • 驗證Verification),主要就是驗證讀取到的內(nèi)容是不是和規(guī)范中規(guī)定的格式完全匹配,如果不匹配,那么類加載失敗,并且會拋出異常;一個.class文件的格式如下:img通過觀察.class文件結(jié)構(gòu),其實.class文件把.java文件的核心信息都保留了下來,只不過是使用二進制的方式重新進行組織了,.class文件是二進制文件,這里的格式有嚴(yán)格說明的,哪幾個字節(jié)表示什么,java官方文檔都有明確規(guī)定。 來自官方文檔:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.1
  • 準(zhǔn)備Preparation),給類對象分配內(nèi)存空間(先在元數(shù)據(jù)區(qū)占個位置),并為類中定義的靜態(tài)變量分配內(nèi)存,此時類變量初始值也就都為 0 值了。
  • 解析Resolution),針對字符串常量初始化,將符號引用轉(zhuǎn)為直接引用;字符串常量,得有一塊內(nèi)存空間,存這個字符的實際內(nèi)容,還得有一個引用來保存這個內(nèi)存空間的起始地址;在類加載之前,字符串常量是在.class文件中的,此時這個引用記錄的并非是字符串常量真正的地址,而是它在文件的偏移量/占位符(符號引用),也就是說,此時常量之間只是知道它們彼此之間的相對位置,不知道自己在內(nèi)存中的實際地址;在類加載之后,才會真正的把這個字符串常量給填充到特定的內(nèi)存地址上中,這個引用才能被真正賦值成指定內(nèi)存地址(直接引用),此時字符串常量之間相對位置還是一樣的;這個場景可以想象你看電影時拿著電影票入場入座。

第三步,初始化(Initialization),這里是真正地對類對象進行初始化,特別是靜態(tài)成員,調(diào)用構(gòu)造方法,進行成員初始化,執(zhí)行代碼塊,靜態(tài)代碼塊,加載父類…

🎯類加載的時機

類加載并不是 Java 程序(JVM)一運行就把所有類都加載了,而是真正用到哪個類才加載哪個;整體是一個“懶加載”的策略;只有需要用的時候才加載(非必要,不加載),就會觸發(fā)以下的加載:

  1. 構(gòu)造類的實例
  2. 調(diào)用這個類的靜態(tài)方法/使用靜態(tài)屬性
  3. 加載子類就會先加載其父類

一旦加載過后后續(xù)使用就不必加載了。

2. 雙親委派模型

雙親委派模型是類加載中的一個環(huán)節(jié),屬于加載階段,它是描述如何根據(jù)類的全限定名找到.class文件的過程。

在 JVM 里面提供了一組專門的對象,用來進行類的加載,即類加載器,當(dāng)然既然雙親委派模型是類加載中的一部分,所以其所描述找.class文件的過程也是類加載器來負責(zé)的。

但是想要找全.class文件可不容易,畢竟.class文件可能在 jdk 目錄里面,可能在項目的目錄里面,還可能在其他特定的位置,因此 JVM 提供了多個類加載器,每一個類加載器負責(zé)在一個片區(qū)里面找。

默認的類加載器主要有三個:

  • BootStrapClassLoader,負責(zé)加載 Java 標(biāo)準(zhǔn)庫里面的類,如 String,Random,Scanner 等。
  • ExtensionClassLoader,負責(zé)加載 JVM 擴展庫中的類,是規(guī)范之外,由實現(xiàn) JVM 的組織(Sun/Oracle),提供的額外的功能。
  • ApplicationClassLoader,負責(zé)加載當(dāng)前項目目錄中自己寫的類以及第三方庫中的類。

除了默認的幾個類加載器,程序員還可以自定義類加載器,來加載其他目錄的類,此時也不是非要遵守雙親委派模型,如 Tomcat 就自定義了類加載器,用來專門加載webapps目錄中的.class文件就沒有遵守。

img

雙親委派模型就描述了類加載過程中的找目錄的環(huán)節(jié),它的過程如下:

如果一個類加載器收到了類加載的請求,首先需要先給定一個類的全限定類名,如:“java.lang.String”。

根據(jù)類的全限定名找的過程中它不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每一個層次的類加載器都是如此。

因此所有的加載請求最終都應(yīng)該傳送到頂層的啟動類加載器中,只有當(dāng)父加載器反饋自己無法完成這個加載請求(它的搜索范圍中沒有找到所需的類)時,子加載器才會嘗試自己去加載(去自己的片區(qū)搜索)。

舉個例子:我們要去找標(biāo)準(zhǔn)庫里面的String.class文件,它的過程大致如下:

  • 首先ApplicationClassLoader類收到類加載請求,但是它先詢問父類加載器是否加載過,即詢問ExtensionClassLoader類是否加載過。
  • 如果ExtensionClassLoader類沒有加載過,請求就會向上傳遞到ExtensionClassLoader類,然后同理,詢問它的父加載器BootstrapClassLoader是否加載過。
  • 如果BootstrapClassLoader沒有加載過,則加載請求就會到BootstrapClassLoader加載器這里,由于BootstrapClassLoader加載器是最頂層的加載器,它就會去標(biāo)準(zhǔn)庫進行搜索,看是否有String類,我們知道String是在標(biāo)準(zhǔn)庫中的,因此可以找到,請求的加載任務(wù)完成,這個過程也就結(jié)束了。

img
再比如,這里要加載我自己寫的的Test類,過程如下:

  • 首先ApplicationClassLoader類收到類加載請求,但是它先詢問父類加載器是否加載過,即詢問ExtensionClassLoader類是否加載過。
  • 如果ExtensionClassLoader類沒有加載過,請求就會向上傳遞到ExtensionClassLoader類,然后同理,詢問它的父加載器BootstrapClassLoader是否加載過。
  • 如果BootstrapClassLoader沒有加載過,則加載請求就會到BootstrapClassLoader加載器這里,由于BootstrapClassLoader加載器是最頂層的加載器,它就會去標(biāo)準(zhǔn)庫進行搜索,看是否有Test類,我們知道Test類不在標(biāo)準(zhǔn)庫,所以會回到子加載器里面搜索。
  • 同理,ExtensionClassLoader加載器也沒有Test類,會繼續(xù)向下,到ApplicationClassLoader加載器中尋找,由于ApplicationClassLoader加載器搜索的就是項目目錄,因此可以找到Test類,全過程結(jié)束。

如果在ApplicationClassLoader還沒有找到,就會拋出異常。
img
總的來說,雙親委派模型就是找.class文件的過程,其實也沒啥,就是名字挺哄人。

img

之所以有上述的查找順序,大概是因為 JVM 代碼是按照類似于遞歸的方式來實現(xiàn)的,就導(dǎo)致了從下到上,又從上到下過程,這個順序,最主要的目的,就是為了保證 Bootstrap 能夠先加載,Application 能夠后加載,這就可以避免說因為用戶創(chuàng)建了一些奇怪的類,引起不必要的 bug。

三. GC垃圾回收機制

在 C/C++ 中內(nèi)存空間是需要進行手動釋放,如果沒有手動去釋放那么這塊內(nèi)存空間就會持續(xù)存在,一直到進程結(jié)束,并且堆的內(nèi)存生命周期比較長,不像棧隨著方法執(zhí)行結(jié)束自動銷毀釋放,堆默認是不能自動釋放的,這就可能導(dǎo)致內(nèi)存泄露的問題,進一步導(dǎo)致后續(xù)的內(nèi)存申請操作失敗。

而在 Java 中引入了 GC 垃圾回收機制,垃圾指的是我們不再使用的內(nèi)存,垃圾回收就是把我們不用的內(nèi)存自動釋放了。

GC的好處:

  • 非常省心,使程序員寫代碼更簡單一些,不容易出錯。

GC的壞處:

  • 需要消耗額外的系統(tǒng)資源,也有額外的性能開銷。
  • GC 這里還有一個嚴(yán)重的 STW(stop the world)問題,如果有時候,內(nèi)存中的垃圾已經(jīng)很多了,這個時候觸發(fā)一次 GC 就會消耗大量系統(tǒng)資源,其他程序可能就無法正常執(zhí)行了;GC 可能會涉及一些鎖操作,就可能導(dǎo)致業(yè)務(wù)代碼無法正常執(zhí)行;極端情況下可會卡頓幾十毫秒甚至上百毫秒。

GC 的實際工作過程包含兩部分:

  1. 找到/判定垃圾。
  2. 再進行垃圾的釋放。

1. 找到需要回收的內(nèi)存

1.1 哪些內(nèi)存需要回收?

Java 程序運行時,內(nèi)存分為四個區(qū),分別是程序計數(shù)器,棧,堆,方法區(qū)。
對于程序計數(shù)器,它占據(jù)固定大小的內(nèi)存,它是隨著線程一起銷毀的,不涉及釋放,那么也就用不到 GC;對于??臻g,函數(shù)執(zhí)行完畢,對應(yīng)的棧幀自動銷毀釋放了,也不需要 GC;對于方法區(qū),主要進行類加載,雖然需要進行“類卸載”,此時需要釋放內(nèi)存,但是這個操作的頻率是非常低的;最后對于堆空間,經(jīng)常需要釋放內(nèi)存,GC 也是主要針對堆進行釋放的。

在堆空間,內(nèi)存的分布有三種,一是正在使用的內(nèi)存,二是不用了但未回收的內(nèi)存,三是未分配的內(nèi)存,那內(nèi)存中的對象,也有三種情況,對象內(nèi)存全部在使用(相當(dāng)于對象整體全部在使用),對象的內(nèi)存部分在使用(相當(dāng)于對象的一部分在使用),對象的內(nèi)存不使用(對象也就使用完畢了),對于這三類對象,前兩類不需要回收,只有最后一類是需要回收的。
img
所以,垃圾回收的基本單位是對象,而不是字節(jié),對于如何找到垃圾,常用有引用計數(shù)法與可達性分析法兩種方式,關(guān)鍵思路是,抓住這個對象,看看到底有沒有“引用”指向它,沒有引用了,它就是需要被釋放的垃圾。

1.2 基于引用計數(shù)找垃圾(Java不采取該方案)

所謂基于引用計數(shù)判斷垃圾,就是給每一個對象分配一個計數(shù)器(整數(shù)),來記錄該對象被多少個引用變量所指,每次創(chuàng)建一個引用指向該對,,計數(shù)器就+1,每次該引用被銷毀了計數(shù)器就–1,如果這個計數(shù)器的值為0則表示該對象需要回收,比如有一個Test對象,它被三個引用所指,所以這個 Test 對象所帶計數(shù)器的值就是3。

//偽代碼:
Test t1 = new Test();
Test t2 = t1;
Test t3 = t1;

img

如果上述的偽代碼是在一個方法中,待方法執(zhí)行完畢,方法中的局部引用變量被銷毀,那么Test對象的引用計數(shù)變?yōu)?code>0,此時就會被回收。

由此可見,基于引用計數(shù)的方案非常簡單高效并且可靠,但是它擁有兩個致命缺陷:

  1. 內(nèi)存空間浪費較多(利用率低), 需要給每個對象分配一個計數(shù)器,如果按照4個字節(jié)來算;代碼中的對象非常少時無所謂,但如果對象特別多了,占用的額外空間就會很多,尤其是每個對象都比較小的情況下。
  2. 存在循環(huán)引用的問題,會出現(xiàn)對象既不使用也不釋放的情況,看下面舉例子來分析一下。

有以下一段偽代碼:

class Test {Test t = null;
}//main方法中:
Test t1 = new Test(); // 1號對象, 引用計數(shù)是1
Test t2 = new Test(); // 2號對象, 引用計數(shù)是1
t1.t = t2;            // t1.t指向2號對象, 此時2號對象引用計數(shù)是2
t2.t = t1;            // t1.t指向1號對象, 此時1號對象引用計數(shù)是2

執(zhí)行上述偽代碼,運行時內(nèi)存圖如下:

img

然后,我們把變量t1與t2置為null,偽代碼如下:

//偽代碼:
t1 = null;
t2 = null;

執(zhí)行完上面?zhèn)未a,運行時內(nèi)存圖如下:
img
此時 t1 和 t2 引用銷毀了,一號對象和二號對象的引用計數(shù)都-1,但由于兩個對象的屬性相互指向另一個對象,計數(shù)器結(jié)果都是1而不是0造成對象無法及時得到釋放,而實際上這個兩個對象已經(jīng)獲取不到了(應(yīng)該銷毀了)。

1.3 基于可達性分析找垃圾(Java采取方案)

Java 中的對象都是通過引用來指向并訪問的,一個引用指向一個對象,對象里的成員又指向別的對象。

所謂可達性分析,就是通過額外的線程,將整個 Java 程序中的對象用鏈?zhǔn)?樹形結(jié)構(gòu)把所有對象串起來,從根節(jié)點出發(fā)去遍歷這個樹結(jié)構(gòu),所有能訪問到的對象,標(biāo)記成“可達”,不能訪問到的,就是“不可達”,JVM 有一個所有對象的名單(每 new 一個對象,JVM 都會記錄下來,JVM 就會知道一共有哪些對象,每個對象的地址是什么),通過上述遍歷,將可達的標(biāo)記出來,剩下的不可達的(未標(biāo)記的)就可以作為垃圾進行回收了。

可達性分析的起點稱為GC Roots(就是一個Java對象),一個代碼中有很多這樣的起點,把每個起點都遍歷一遍就完成了一次掃描。
img

對于這個GCRoots,一般很難被回收,它來源可以分為以下幾種:

  • 在虛擬機棧(棧幀中的本地變量表)中引用的對象,例如各個線程被調(diào)用的方法堆棧中使用到的參數(shù)、局部變量、臨時變量等。
  • 在本地方法棧中 JNI(即通常所說的Native方法)引用的對象。
  • 常量池中引用所指向的對象。
  • 方法區(qū)中靜態(tài)成員所指向的對象。
  • 所有被同步鎖(synchronized 關(guān)鍵字)持有的對象。

可達性分析克服了引用計數(shù)的兩個缺點,但它有自己的問題:

  1. 需要進行類似于 “樹遍歷”的過程,消耗更多的時間,但可達性分析操作并不需要一直執(zhí)行,只需要隔一段時間執(zhí)行一次尋找不可達對象,確定垃圾就可以,所以,慢一下點也是沒關(guān)系的,雖遲,但到。
  2. 可達性分析過程,當(dāng)前代碼中的對象的引用關(guān)系發(fā)生變化了,還比較麻煩,所以為了準(zhǔn)確的完成這個過程,就需要讓其他的業(yè)務(wù)暫停工作(STW問題),但 Java 發(fā)展這么多年,垃圾回收機制也在不斷的更新優(yōu)化,STW 這個問題,現(xiàn)在已經(jīng)能夠比較好的應(yīng)對了,雖不能完全消除,但也已經(jīng)可以讓 STW 的時間盡量短了。

2. 垃圾回收算法

垃圾回收的算法最常見的有以下幾種:

  1. 標(biāo)記-清除算法
  2. 標(biāo)記-復(fù)制算法
  3. 標(biāo)記-整理算法
  4. 分代回收算法(本質(zhì)就是綜合上述算法,在堆的不同區(qū)采取不同的策略)

2.1 標(biāo)記-清除算法

標(biāo)記其實就是可達性分析的過程,在可達性分析的過程中,會標(biāo)記可達的對象,其不可達的對象,都會被視為垃圾進行回收。

比如經(jīng)過一輪標(biāo)記后,標(biāo)記狀態(tài)和回收后狀態(tài)如圖:

img
我們發(fā)現(xiàn),內(nèi)存是釋放了,但是回收后,未分配的內(nèi)存空間是零散的不是連續(xù)的,我們知道申請內(nèi)存的時候得到的內(nèi)存得是連續(xù)的,雖然內(nèi)存釋放后總的空閑空間很大,但由于未分配的內(nèi)存是碎片化的,就有可能申請內(nèi)存失敗;假設(shè)你的主機有 1GB 空閑內(nèi)存,但是這些內(nèi)存是碎片形式存在的,當(dāng)申請 500MB 內(nèi)存的時候,也可能會申請失敗,畢竟不能保證有一塊大于 500MB 的連續(xù)內(nèi)存空間,這也是標(biāo)記-清除算法的缺陷(內(nèi)存碎片問題)。

2.2 標(biāo)記-復(fù)制算法

為了解決標(biāo)記-清除算法所帶來的內(nèi)存碎片化的問題,引入了復(fù)制算法。

它將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊,每次清理,就將還存活著的對象復(fù)制到另外一塊上面,然后再把已使用過的這一塊內(nèi)存空間一次清理掉。

復(fù)制算法的第一步還是要通過可達性分析進行標(biāo)記,得到哪一部分需要進行回收,哪一部分需要保留,不能回收。

標(biāo)記完成后,會將還在使用的內(nèi)存連續(xù)復(fù)制到另外一塊等大的內(nèi)存上,這樣得到的未分配內(nèi)存一直都是連續(xù)的,而不是碎片化的。

img
但是,復(fù)制算法也有缺陷:

  • 空間利用率低。
  • 如果垃圾少,有效對象多,復(fù)制成本就比較大。

2.3 標(biāo)記-整理算法

標(biāo)記-整理算法針對復(fù)制算法做出進一步改進,其中的標(biāo)記過程仍然與“標(biāo)記-清除”算法一致,但后續(xù)步驟不是直接對可回收對象進行清理,而是讓所有存活的對象都向內(nèi)存空間一端移動,然后直接清理掉邊界以外的內(nèi)存。

img
回收時是將存活對象按照某一順序(比如從左到右,從上到下的順序)拷貝到非存活對象的內(nèi)存區(qū)域,類似于順序表的刪除操作,會將后面的元素搬運到前面。
解決了標(biāo)記-復(fù)制算法空間利用率低的問題,也沒有內(nèi)存碎片的問題,但是復(fù)制的開銷問題并沒有得到解決。

2.4 分代回收

上述的回收算法都有一定的缺陷,分代回收就是將上述三種算法結(jié)合起來分區(qū)使用,分代回收會針對對象進行分類,以熬過的 GC 掃描輪數(shù)作為“年齡”,然后針對不同年齡采取不同的方案

分代是基于一個經(jīng)驗規(guī)律,如果一個東西存在時間長了,那么接下來大概率也會存在(要沒有早就沒有了)。

我們知道 GC 主要是回收堆上的無用內(nèi)存,我們先來了解一下堆的劃分,堆包括新生代(Young)、老年代(Old),而新生代包括一個伊甸區(qū)(Eden)與兩個幸存區(qū)(Survivor),分代回收算法就會根據(jù)不同的代去采取不同的標(biāo)記-xx算法。

img
在新生代,包括一個伊甸區(qū)與兩個幸存區(qū),伊甸區(qū)存儲的是未經(jīng)受 GC 掃描的對象(年齡為 0),也就是剛剛 new 出來的對象。

幸存區(qū)存儲了經(jīng)過若干輪 GC 掃描的對象,通過實際經(jīng)驗得出,大部分的 Java 對象具有“朝生夕滅”的特點,生命周期非常短,也就是說只有少部分的伊甸區(qū)對象才能熬過第一輪的 GC 掃描到幸存區(qū),所以到幸存區(qū)的對象相比于伊甸區(qū)少的多,正因為大部分新生代的對象熬不過 GC 第一輪掃描,所以伊甸區(qū)與幸存區(qū)的分配比例并不是1:1的關(guān)系,HotSpot 虛擬機默認一個 Eden 和一個 Survivor 的大小比例是 8∶1,正因為新生代的存活率較小,所以新生代使用的垃圾回收算法為標(biāo)記-復(fù)制算法最優(yōu),畢竟存活率越小,對于標(biāo)記-復(fù)制算法,復(fù)制的開銷也就很小。

不妨我們將第一個 Survivor 稱為活動空間,第二個 Survivor 稱為空閑空間,一旦發(fā)生 GC,會將 10% 的活動區(qū)間與另外 80% 伊甸區(qū)中存活的對象復(fù)制到 10% 的空閑空間,接下來,將之前 90% 的內(nèi)存全部釋放,以此類推。

在后續(xù)幾輪 GC 中,幸存區(qū)對象在兩個 Survivor 中進行標(biāo)記-復(fù)制算法,此處由于幸存區(qū)體積不大,浪費的空間也是可以接受的。

在繼續(xù)持續(xù)若干輪 GC 后(這個對象已經(jīng)再兩個幸存區(qū)中來回考貝很多次了),幸存區(qū)的對象就會被轉(zhuǎn)移到老年代,老年代中都是年齡較老的對象,根據(jù)經(jīng)驗,一個對象越老,繼續(xù)存活的可能性就越大(要掛早掛了),因此老年代的 GC 掃描頻率遠低于新生代,所以老年代采用標(biāo)記-整理的算法進行內(nèi)存回收,畢竟老年代存活率高,對于標(biāo)記-整理算法,復(fù)制轉(zhuǎn)移的開銷很低。

還要注意一個特殊情況,如果對象非常大,就直接進入老年代,因為大對象進行復(fù)制算法,成本比較高,而且大對象也不會很多。

http://aloenet.com.cn/news/45544.html

相關(guān)文章:

  • 做英語趣味教具的網(wǎng)站時事新聞最新2022
  • 網(wǎng)站開發(fā)運營優(yōu)化百度漲
  • 做一個電子商務(wù)網(wǎng)站麗水網(wǎng)站seo
  • 工商企業(yè)查詢網(wǎng)楓樹seo網(wǎng)
  • 丹徒網(wǎng)站建設(shè)要多少錢百度seo刷排名網(wǎng)址
  • 做一個簡單的公司網(wǎng)站要多少錢虎撲體育網(wǎng)體育
  • 煙臺網(wǎng)站的優(yōu)化seo網(wǎng)絡(luò)運營
  • 網(wǎng)站建設(shè)延期合同書百度競價是什么工作
  • 縉云做網(wǎng)站每天新聞早知道
  • 做網(wǎng)站可以做什么seo推廣優(yōu)化
  • 最好的建站網(wǎng)站seo優(yōu)化一般多少錢
  • 響應(yīng)式網(wǎng)站的寬度張家港seo建站
  • google網(wǎng)站收錄企業(yè)網(wǎng)站seo案例分析
  • 上海的做網(wǎng)站的公司網(wǎng)絡(luò)推廣技術(shù)外包
  • 站長工具排名查詢重慶網(wǎng)站建設(shè)軟件
  • 企業(yè)網(wǎng)站報價表關(guān)于軟文營銷的案例
  • 什么平臺賣軟件長沙專業(yè)競價優(yōu)化首選
  • 內(nèi)蒙古企業(yè)網(wǎng)站制作南寧網(wǎng)絡(luò)推廣服務(wù)商
  • 張掖市住房和城鄉(xiāng)建設(shè)局網(wǎng)站網(wǎng)絡(luò)營銷的網(wǎng)站建設(shè)
  • 手機h5建站網(wǎng)站優(yōu)化方案模板
  • 網(wǎng)站默認樣式表上海知名網(wǎng)站制作公司
  • 做網(wǎng)站需要編程推廣點擊器
  • 做影視免費網(wǎng)站違法嗎百度官網(wǎng)網(wǎng)站登錄
  • 深圳學(xué)網(wǎng)站開發(fā)關(guān)鍵詞挖掘站網(wǎng)
  • wordpress數(shù)據(jù)庫出錯山東進一步優(yōu)化
  • 佛山網(wǎng)站如何制作云南seo網(wǎng)絡(luò)優(yōu)化師
  • 中國建設(shè)委員會的官方網(wǎng)站seo免費視頻教程
  • 醫(yī)院網(wǎng)站建設(shè)情況電商推廣平臺
  • 響應(yīng)式網(wǎng)站無法做百度聯(lián)盟最新seo操作
  • 科技網(wǎng)站實例上海seo推廣整站