亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JVM的分代模型是什么

發布時間:2020-10-27 22:38:47 來源:億速云 閱讀:152 作者:Leah 欄目:開發技術

這期內容當中小編將會給大家帶來有關JVM的分代模型是什么,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

我們將針對jvm堆內存的分代模型做一個詳細的解析,和大家一起輕松理解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的運行機制。

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

接著在執行load()方法時,會在java堆內存中創建一個SysUser對象實例,而棧幀中會有sysUser局部變量引用堆內存中的SysUser對象實例。

如下圖:

JVM的分代模型是什么

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

變量的存活時間

現在我們思考一下會發現,這個SysUser對象實際上屬于一個短暫存活的對象,因為在load()方法執行完畢后,load()方法的棧幀就會出棧。

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

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

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

所以這個SysUser對象實例是一個存活時間很短的對象,可能在執行load()方法的時候被創建出來,執行之后就被垃圾回收掉了。

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

現在我們將上邊的代碼改造一下:

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");
  }
}

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

JVM的分代模型是什么

分代模型

接下來我們進入核心內容,就是jvm的分代模型了。

上文中我們發現,根據我們的編碼方式的不同,采用不同的方式創建和使用對象,對象的存活時間是不同的。

所以jvm將內存區分為兩個區域:年輕代和老年代。

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

老年代就是第二種靜態變量的示例,創建后需要長期在堆內存中存活。

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

其實這與垃圾回收機制是密不可分的。

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

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

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

新生代的垃圾回收

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

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

其實不是這樣的,垃圾回收是有觸發條件的。

有一個比較常見的場景是這樣的,假設我們的代碼中創建了大量的對象,導致堆內存中囤積了大量的對象,然后這些對象現在都沒有人引用了。

這個時候,如果新生代預先分配的內存空間被占滿了,那么我們的代碼此時要新創建一個對象的時候,發現新生代空間滿了,怎么辦?

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

下圖表達了這一過程:

JVM的分代模型是什么

長期存活的對象什么時候進入老年代

接下來我們談論一個話題,靜態變量引用的長期存活的對象是什么時候進入老年代的。

上文我們了解到,新生代的對象會經歷一次次的垃圾回收,而被靜態變量引用的對象因為一直被引用,所以一直不會被回收,所以此時jvm就有了一條規定。

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

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

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

答案是肯定的,因為老年代里的對象隨著代碼的運行,也是可以不再被任何人引用的,就需要垃圾回收了。

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

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

上述就是小編為大家分享的JVM的分代模型是什么了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

兴业县| 宜丰县| 黄山市| 壶关县| 峨山| 叶城县| 凤阳县| 固镇县| 那坡县| 灵台县| 繁峙县| 仪征市| 滨海县| 顺义区| 新化县| 望都县| 黄冈市| 汾阳市| 永新县| 元氏县| 苏尼特右旗| 霍林郭勒市| 九江市| 杨浦区| 宜兴市| 怀来县| 大连市| 隆德县| 乐至县| 武鸣县| 抚松县| 秦皇岛市| 弥勒县| 湖南省| 丰台区| 贡山| 广州市| 司法| 莆田市| 南皮县| 鄂州市|