亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解JVM的分代模型

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

前言

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

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

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

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

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

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

}

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

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

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

如下圖:

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

變量的存活時(shí)間

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

而一旦出棧,就沒(méi)有了sysUser這個(gè)局部變量來(lái)引用SysUser這個(gè)對(duì)象的實(shí)例。

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

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

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

而這種對(duì)象在我們平時(shí)的開(kāi)發(fā)中是很常見(jiàn)的,占絕大多數(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對(duì)象實(shí)例就會(huì)一直被這個(gè)靜態(tài)變量引用,所以不會(huì)被垃圾回收,一直保存在堆內(nèi)存中。如下圖:

分代模型

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

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

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

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

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

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

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

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

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

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

新生代的垃圾回收

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

那么問(wèn)題來(lái)了,是沒(méi)有引用后就會(huì)立即發(fā)生垃圾回收,回收掉沒(méi)有被引用的對(duì)象實(shí)例嗎?

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

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

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

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

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

長(zhǎng)期存活的對(duì)象什么時(shí)候進(jìn)入老年代

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

上文我們了解到,新生代的對(duì)象會(huì)經(jīng)歷一次次的垃圾回收,而被靜態(tài)變量引用的對(duì)象因?yàn)橐恢北灰?,所以一直不?huì)被回收,所以此時(shí)jvm就有了一條規(guī)定。

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

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

那么老年代中的對(duì)象會(huì)被垃圾回收嗎?

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

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

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

總結(jié)

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

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

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

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

相關(guān)文章

  • java仿windows記事本小程序

    java仿windows記事本小程序

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

    Java中的MapStruct用法詳解

    這篇文章主要介紹了Java中的MapStruct用法詳解,MapStuct的使用非常簡(jiǎn)單,把對(duì)應(yīng)的jar包引入即可,本文通過(guò)示例代碼給大家介紹的非常詳細(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)變量賦值教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lá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)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • 深入淺出重構(gòu)Mybatis與Spring集成的SqlSessionFactoryBean(上)

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

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

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

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

    SpringBoot自動(dòng)重啟的兩種方法

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

    springboottest測(cè)試依賴和使用方式

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

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

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

最新評(píng)論