最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JVM內(nèi)存回收機制使用及說明

 更新時間:2026年04月30日 09:27:00   作者:Nova??  
文章簡要介紹了JVM運行時數(shù)據(jù)區(qū)、類加載過程、雙親委派模型和垃圾回收機制,其中包括堆區(qū)、棧、程序計數(shù)器、元數(shù)據(jù)區(qū)等組成部分,以及類加載的五個步驟、雙親委派模型的類加載順序、垃圾回收的四種算法、分代回收的原理和G1垃圾回收算法

1.JVM運行時數(shù)據(jù)區(qū)

JVM運行時數(shù)據(jù)區(qū)域 也叫做:JVM內(nèi)存布局。

JVM內(nèi)存布局 和 java內(nèi)存模型完全不同,JVM內(nèi)存布局由5大部分組成。

1.堆區(qū)(線程共享):程序中所有創(chuàng)建的對象都保存在堆中。JVM最大空間。

2.棧(線程私有)

  • java虛擬機棧作用(線程私有):Java虛擬機棧的生命周期 和 線程相同Java虛擬機棧描述了java方法執(zhí)行的內(nèi)存模型每個方法在執(zhí)行時 都會創(chuàng)建一個棧幀,用來儲存局部變量,方法之間的調(diào)用關(guān)系,動態(tài)鏈接,方法出口等等。
  • 本地方法棧:與虛擬機棧類似,只不過是給本地方法使用的,本地方法由C++代碼編寫。

3.程序計數(shù)器(線程私有)保存下一條要執(zhí)行的指令的地址。這里不是CPU寄存器儲存的,而是內(nèi)存空間,指令是java的字節(jié)碼。不是二進制機器語言。

4.元數(shù)據(jù)區(qū):(以前叫方法區(qū))保存java代碼中涉及類的相關(guān)信息。類的static屬性。

在一個java進程中,元數(shù)據(jù)區(qū) 和 堆 是只有一份的。即同一個進程中的所有線程共用一份數(shù)據(jù)。

一個java進程中有多個線程,多個線程都有自己的 程序計數(shù)器 和 棧。所以每個線程都需要保存自己的“程序計數(shù)器” 每個線程都需要記錄自己的 調(diào)用關(guān)系。

檢測一下是掌握的怎么樣,下面代碼中的變量都儲存在哪些區(qū)域?

public class test4 {
    static class  Test{
        private int a;
        private Test b = new Test();
        private static int c;
        private static Test d = new Test();
    }
    public static void main(String[] args) {
        int e = 10;
        Test f = new Test();
    }
}

一般地:

  • 局部變量:棧
  • 成員變量:堆
  • 靜態(tài)成員變量:元數(shù)據(jù)區(qū)(方法區(qū))

2.JVM類加載過程

一個類的生命周期大致為下幾個過程。

編寫一個java程序 會得到一個 .java文件,在經(jīng)過javac 編譯 就會得到一個 .class文件。

想要運行java 進程,jvm就需要 讀取 .class 文件并執(zhí)行里面的指令。

  • jvm讀取到 .class里面的內(nèi)容 這個就是類加載。把類 涉及的字節(jié)碼,從硬盤讀取到 內(nèi)存里。
  • 加載一個 .claas文件,就會對應(yīng)創(chuàng)建一個類對象。類對象包含了.class文件里的各種信息。
  • 類名字,類的屬性,類有哪些方法,繼承的父類有哪些,實現(xiàn)的接口有哪些....

具體步驟:

1.加載:把 .class 文件找到,然后打開并讀取文件的內(nèi)容。

代碼中先見到 類的名字,然后進一步找到對應(yīng)的 .class 文件(涉及一系列的目錄查找過程

2.驗證驗證讀到的 .class 文件的數(shù)據(jù)是否正確,是否合法。

java標準文檔中明確規(guī)定 .class 文件的格式是怎么樣的。

3.準備:分配內(nèi)存空間。

根據(jù)讀取到的內(nèi)容大小,確定出類對象需要的內(nèi)存空間,申請這樣大小的空間,并把這個空間全部初始化為0.

4.解析:主要針對類中的字符串常量進行處理

java虛擬機 將字符串常量池中的 符號引用 替換為直接引用的過程,也就是初始化常量。

符號引用 其實就是指(字符串常量已經(jīng)在 .class文件中)文件中 符號的位置,就是偏移量。

直接引用 就是直接保存變量的地址。

5.初始化:針對 類對象 做最終的初始化操作,執(zhí)行靜態(tài)成員賦值語句。

3.雙清委派模型

操作: 輸入一個 類的全限定名(類似于java.lang.String),的到對應(yīng)的 .class 文件。

屬于 jvm加載類中的第一個機制:加載

  • Bootstrap ClassLoader(加載 標準庫中的類)
  • ExtensionClassLoader(加載 擴展庫的類)
  • ApplicationClassLoader(負責加載第三方庫的類)

為什么會是這個流程?

核心目的是 方式用戶自己寫的類把 標準庫 或者 擴展庫給覆蓋掉。

保證 標準庫的類是第一位,擴展庫的類的是第二位。最后是第三方庫的類。

防止程序員 不小心創(chuàng)建一個 和 系統(tǒng)中已有的類重名的類。導致加載的時候覆蓋掉了系統(tǒng)的類。

4.垃圾回收機制(GC)

GC 主要存在哪里呢?

棧 和 程序計數(shù)器 主要都是跟隨線程的結(jié)束而結(jié)束。

元數(shù)據(jù)區(qū):類對象涉及到的類加載,一個程序里面嗎要加載得類都是有上限的,不會出現(xiàn)無限增長的情況。

所以 堆是GC得主要戰(zhàn)區(qū)。

垃圾回收,回收內(nèi)存 都是一對象為維度進行回收的。

GC回收的流程:

  • 1.找出誰是垃圾        
  • 2.釋放垃圾的內(nèi)存空間

找出誰是垃圾方案一:引用計數(shù)

給每個對象分配一個計數(shù)器,衡量有多少個引用指向。

  • 每增加一個引用,計數(shù)器+1
  • 每減少一個引用,計數(shù)器-1,如果計數(shù)器為0,此對象就垃圾了需要回收。

此時 對象中的計數(shù)器為0,就視為垃圾,需要回收。

上述方案存在兩個問題:

1.消耗額外空間去 儲存計數(shù)器

假設(shè)Tets類,只有一個int(4字節(jié))成員,那么就要花2個字節(jié)儲存計數(shù)器,內(nèi)存多用了 50%

2.引用計數(shù)可能會導致“循環(huán)引用”,使得上述判定出錯。

這種情況就是最后 這倆對象計數(shù)器都不是0,都不能被釋放。

找出誰是垃圾:方案二,可達性分析

用時間換取空間。

JVM中專門搞了一波周期性的線程,掃面代碼中的所有對象,判定某個對象是否“可達”。

對應(yīng)的,不可達的就是垃圾。

  • JVM中有所有對象的總名單,按照名單點名,如果沒有到的 ,就是垃圾。
  • JVM中有很多的root根,從這個root開始可以把所有的對象都遍歷到。遍歷不到但是名單上存在就是垃圾。

釋放垃圾的內(nèi)存空間

1.標記-清除法

如果直接對內(nèi)存空間進行標記清楚,就有可能導致碎片化的空間無法充分利用。

這樣剩下的三個空間就不容易利用了,碎片化的空間不能進行申請連續(xù)的空間。

2.復(fù)制算法

將被回收后的空間的一分為二,把不是垃圾的對象拷貝到另一側(cè)。確?;厥蘸蟮玫竭B續(xù)的空間

這個算法缺點很明顯:

1.內(nèi)存空間利用率低

2.如果存活下來的對象比較多,復(fù)制成本也很大。

3.標記-整理

與標記-清楚類似,但是不一樣的是后續(xù)并不是直接回收對象,而是讓所有的存活對象都向前移動,最后直接清理掉邊界標記的就可以了。

4.jvm中真正的解決方案。

判斷垃圾:jvm依據(jù)對象的年齡對 對象進行區(qū)域劃分

如果獲得年齡,使用可達性分析 對對象進行掃描,每次描掃后對象的年齡就+1

1.伊甸區(qū)比較大,讓新創(chuàng)建的對象存放,大多數(shù)新創(chuàng)建的對象都活不過第一輪GC,留下來的對象拷貝到幸存區(qū)。

2.幸存區(qū),是兩個相按照復(fù)制算法將存活久對象復(fù)制到幸存區(qū),反復(fù)多次。幸存區(qū)里也會為了保留完整空間進行左右多次復(fù)制。

3.一個對象在幸存區(qū)多次被拷貝,年齡不斷增長,就要拷貝到老年代了。

4.根據(jù)經(jīng)驗規(guī)律,老年代的對象生命周期都比較長,即便如此也是要進行可達性分析的。

但是老年代的GC頻率較低。老年代也需要通過標記整理。

回收垃圾方式:分代回收

分代回收時JVM的GC基本思想方法。

jvm還提供許多“垃圾回收器”對上述的分代回收 作進一步的擴充和具體實現(xiàn)。

CMS涉及理念,把整個GC過程拆分成多個階段,能和業(yè)務(wù)線程并發(fā)運行的。就盡量并發(fā)減少STW時間。

G1把整個內(nèi)存分成很多快,不同的顏色表示這個一塊區(qū)域是哪一塊(新生代,老年代,幸存區(qū)...)

進行GC時不要求一周期就把多個內(nèi)存都回收,只要回收一部分就好。限制一輪GC的工作量,目的是使STW控制在一定范圍,降低STW的影響。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

北安市| 潜江市| 大余县| 临汾市| 宣化县| 富蕴县| 莱州市| 称多县| 肇源县| 罗平县| 曲麻莱县| 镇赉县| 日照市| 灌阳县| 阿坝县| 通州区| 天津市| 民和| 泉州市| 安丘市| 黑龙江省| 含山县| 赤峰市| 康定县| 静乐县| 阿拉尔市| 托克逊县| 格尔木市| 徐闻县| 德安县| 河津市| 保山市| 全椒县| 曲阳县| 孟州市| 沁源县| 万宁市| 阿拉善左旗| 阿拉善盟| 壤塘县| 垣曲县|