欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解JVM的分代模型

 更新時間:2020年10月15日 14:19:33   作者:H.U.C-王子  
這篇文章主要介紹了JVM的分代模型的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java虛擬機(jī)相關(guān)知識,感興趣的朋友可以了解下

前言

上篇文章我們一起對jvm的內(nèi)存模型有了比較清晰的認(rèn)識,小伙伴們可以參考JVM內(nèi)存模型不再是秘密這篇文章做一個復(fù)習(xí)。

本篇文章我們將針對jvm堆內(nèi)存的分代模型做一個詳細(xì)的解析,和大家一起輕松理解jvm的分代模型。

相信看過其他文章的小伙伴們可能都知道,jvm的分代模型包括:年輕代、老年代、永久代。

那么它們分別代表著什么角色呢?我們先來看一段代碼

public class Main {
  public static void main(String[] args) {
    while (true){
      load();
    }
  }

  public static void load(){
    SysUser sysUser = new SysUser();
    sysUser.setAvatar("1");
  }

}

這段代碼本身沒有什么特殊的含義,主要是理解jvm的運(yùn)行機(jī)制。

首先一旦執(zhí)行main()方法,就會把main()方法的棧幀壓入main線程的虛擬機(jī)棧,然后調(diào)用load()方法后,又會把load()方法的棧幀壓入虛擬機(jī)棧。

接著在執(zhí)行l(wèi)oad()方法時,會在java堆內(nèi)存中創(chuàng)建一個SysUser對象實(shí)例,而棧幀中會有sysUser局部變量引用堆內(nèi)存中的SysUser對象實(shí)例。

如下圖:

到這里上篇文章都講解過,相信大家都能看懂。

變量的存活時間

現(xiàn)在我們思考一下會發(fā)現(xiàn),這個SysUser對象實(shí)際上屬于一個短暫存活的對象,因?yàn)樵趌oad()方法執(zhí)行完畢后,load()方法的棧幀就會出棧。

而一旦出棧,就沒有了sysUser這個局部變量來引用SysUser這個對象的實(shí)例。

所以,其實(shí)這個SysUser對象已經(jīng)沒有用了,但是它還在占用著堆內(nèi)存的空間,那么對于這種沒有引用的對象實(shí)例jvm是如何處理的呢?

這就要說到j(luò)vm的垃圾回收機(jī)制了,jvm本身是有垃圾回收機(jī)制的,它是一個后臺線程,會把沒有人引用的SysUser對象實(shí)例給回收掉,不斷的釋放內(nèi)存空間。

所以這個SysUser對象實(shí)例是一個存活時間很短的對象,可能在執(zhí)行l(wèi)oad()方法的時候被創(chuàng)建出來,執(zhí)行之后就被垃圾回收掉了。

而這種對象在我們平時的開發(fā)中是很常見的,占絕大多數(shù)比例。

現(xiàn)在我們將上邊的代碼改造一下:

public class Main {
  private static SysUser sysUser = new SysUser();
  public static void main(String[] args) {
    while (true){
      load();
    }
  }

  public static void load(){
    sysUser.setAvatar("1");
  }
}

其實(shí)就是把局部變量sysUser變成了靜態(tài)變量,這樣修改后,sysUser不在作為局部變量保存在棧中,而是和class類文件一起保存在方法區(qū)中,這樣SysUser對象實(shí)例就會一直被這個靜態(tài)變量引用,所以不會被垃圾回收,一直保存在堆內(nèi)存中。如下圖:

分代模型

接下來我們進(jìn)入核心內(nèi)容,就是jvm的分代模型了。

上文中我們發(fā)現(xiàn),根據(jù)我們的編碼方式的不同,采用不同的方式創(chuàng)建和使用對象,對象的存活時間是不同的。

所以jvm將內(nèi)存區(qū)分為兩個區(qū)域:年輕代和老年代。

年輕代就是我們的第一種局部變量的示例,創(chuàng)建和使用完畢后會被垃圾回收掉。

老年代就是第二種靜態(tài)變量的示例,創(chuàng)建后需要長期在堆內(nèi)存中存活。

相信到這里大家就應(yīng)該理解了什么樣的對象是短期存活的對象,什么樣的對象是長期存活的對象,那么它們是如何分別存在年輕代和老年代中的呢?為什么要這么區(qū)分呢?

其實(shí)這與垃圾回收機(jī)制是密不可分的。

對于年輕代里的對象,他們的特點(diǎn)是創(chuàng)建后很快就會被回收,而對于老年代里的對象,他們的特點(diǎn)是需要長期存活,所以這兩種對象是不能用一種垃圾回收算法進(jìn)行回收的,所以需要區(qū)分成兩個。

對于長期存在的靜態(tài)變量sysUser,其實(shí)剛開始的時候也是在年輕代的,那它是什么時候進(jìn)入老年代的呢?我們下文會講解這個問題。

那永久代又是什么呢?其實(shí)永久代就是我們說的jvm的方法區(qū),用于存放一下類信息的,這部分之后的文章涉及到會詳解,現(xiàn)在理解到這就可以了。

新生代的垃圾回收

前文我們了解了,當(dāng)load方法執(zhí)行完畢出棧后,里面的局部變量sysUser就沒了,堆內(nèi)存中的SysUser對象就沒有引用了,所以會被垃圾回收掉。

那么問題來了,是沒有引用后就會立即發(fā)生垃圾回收,回收掉沒有被引用的對象實(shí)例嗎?

其實(shí)不是這樣的,垃圾回收是有觸發(fā)條件的。

有一個比較常見的場景是這樣的,假設(shè)我們的代碼中創(chuàng)建了大量的對象,導(dǎo)致堆內(nèi)存中囤積了大量的對象,然后這些對象現(xiàn)在都沒有人引用了。

這個時候,如果新生代預(yù)先分配的內(nèi)存空間被占滿了,那么我們的代碼此時要新創(chuàng)建一個對象的時候,發(fā)現(xiàn)新生代空間滿了,怎么辦?

這個時候就會觸發(fā)一次新生代的垃圾回收,也稱為“Minor GC”或"Young GC",它會嘗試把新生代中沒有人引用的對象給回收掉,釋放空間。

下圖表達(dá)了這一過程:

長期存活的對象什么時候進(jìn)入老年代

接下來我們談?wù)撘粋€話題,靜態(tài)變量引用的長期存活的對象是什么時候進(jìn)入老年代的。

上文我們了解到,新生代的對象會經(jīng)歷一次次的垃圾回收,而被靜態(tài)變量引用的對象因?yàn)橐恢北灰茫砸恢辈粫换厥?,所以此時jvm就有了一條規(guī)定。

如果新生代中的對象,在經(jīng)歷了15次垃圾回收后,依然堅(jiān)挺的存活著,那就證明它是個"老年人"了,然后它會被轉(zhuǎn)移到老年代中。

老年代就是存放這些年齡比較大的對象的。

那么老年代中的對象會被垃圾回收嗎?

答案是肯定的,因?yàn)槔夏甏锏膶ο箅S著代碼的運(yùn)行,也是可以不再被任何人引用的,就需要垃圾回收了。

或者說,隨著越來越多的對象進(jìn)入老年代,老年代的內(nèi)存也會被占滿,所以一定是要對老年代進(jìn)行垃圾回收的。

我們暫時不用考慮具體是怎么回收的,這個內(nèi)容在之后的文章中我們會有詳細(xì)的解析。

總結(jié)

今天就給大家準(zhǔn)備了這么多內(nèi)容,可能有些小伙伴覺得還沒看夠,這些內(nèi)容都比較簡單,我已經(jīng)會了,有沒有更深入的東西呢?

別急,學(xué)習(xí)是循序漸進(jìn)的事情,王子是想要用最簡單的大白話來和小伙伴們一起討論jvm的原理的,同時也想找一些案例來和大家一起探討,印象會更深刻。

所以今天小伙伴們了解到這里就可以了,讓我們在后續(xù)的文章中不見不散,深入討論些更深層的內(nèi)容吧。

以上就是詳解JVM的分代模型的詳細(xì)內(nèi)容,更多關(guān)于JVM 分代模型的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java仿windows記事本小程序

    java仿windows記事本小程序

    這篇文章主要為大家詳細(xì)介紹了java仿windows記事本小程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • Java中的MapStruct用法詳解

    Java中的MapStruct用法詳解

    這篇文章主要介紹了Java中的MapStruct用法詳解,MapStuct的使用非常簡單,把對應(yīng)的jar包引入即可,本文通過示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • Spring實(shí)戰(zhàn)之Qualifier注解用法示例

    Spring實(shí)戰(zhàn)之Qualifier注解用法示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之Qualifier注解用法,結(jié)合實(shí)例形式詳細(xì)分析了spring Qualifier注解相關(guān)配置、定義與使用方法,需要的朋友可以參考下
    2019-12-12
  • springboot 使用yml配置文件給靜態(tài)變量賦值教程

    springboot 使用yml配置文件給靜態(tài)變量賦值教程

    這篇文章主要介紹了springboot 使用yml配置文件給靜態(tài)變量賦值教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • java正則表達(dá)式校驗(yàn)日期格式實(shí)例代碼

    java正則表達(dá)式校驗(yàn)日期格式實(shí)例代碼

    如果使用得當(dāng),正則表達(dá)式是匹配各種模式的強(qiáng)大工具,下面這篇文章主要給大家介紹了關(guān)于java正則表達(dá)式校驗(yàn)日期格式的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • 深入淺出重構(gòu)Mybatis與Spring集成的SqlSessionFactoryBean(上)

    深入淺出重構(gòu)Mybatis與Spring集成的SqlSessionFactoryBean(上)

    通常來講,重構(gòu)是指不改變功能的情況下優(yōu)化代碼,但本文所說的重構(gòu)也包括了添加功能。這篇文章主要介紹了重構(gòu)Mybatis與Spring集成的SqlSessionFactoryBean(上)的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • mybatis攔截器及不生效的解決方法

    mybatis攔截器及不生效的解決方法

    本文主要介紹了mybatis攔截器及不生效的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • SpringBoot自動重啟的兩種方法

    SpringBoot自動重啟的兩種方法

    我們在項(xiàng)目開發(fā)階段,可能經(jīng)常會修改代碼,修改完后就要重啟Spring Boot,本文主要介紹了SpringBoot自動重啟的兩種方法,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • springboottest測試依賴和使用方式

    springboottest測試依賴和使用方式

    這篇文章主要介紹了springboottest測試依賴和使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 深入淺出理解Java泛型的使用

    深入淺出理解Java泛型的使用

    這篇文章主要介紹了深入淺出理解Java泛型的使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09

最新評論