久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    深入理解JVM(一)

     月影曉風(fēng) 2017-04-27

    JVM內(nèi)存模型

    Java虛擬機(jī)(Java Virtual Machine=JVM)的內(nèi)存空間分為五個(gè)部分,分別是:
    1. 程序計(jì)數(shù)器
    2. Java虛擬機(jī)棧
    3. 本地方法棧
    4. 堆
    5. 方法區(qū)。

    下面對(duì)這五個(gè)區(qū)域展開(kāi)深入的介紹。

    1. 程序計(jì)數(shù)器

    1.1. 什么是程序計(jì)數(shù)器?

    程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,可以把它看作當(dāng)前線程正在執(zhí)行的字節(jié)碼的行號(hào)指示器。也就是說(shuō),程序計(jì)數(shù)器里面記錄的是當(dāng)前線程正在執(zhí)行的那一條字節(jié)碼指令的地址。
    注:但是,如果當(dāng)前線程正在執(zhí)行的是一個(gè)本地方法,那么此時(shí)程序計(jì)數(shù)器為空。

    1.2. 程序計(jì)數(shù)器的作用

    程序計(jì)數(shù)器有兩個(gè)作用:

    1. 字節(jié)碼解釋器通過(guò)改變程序計(jì)數(shù)器來(lái)依次讀取指令,從而實(shí)現(xiàn)代碼的流程控制,如:順序執(zhí)行、選擇、循環(huán)、異常處理。
    2. 在多線程的情況下,程序計(jì)數(shù)器用于記錄當(dāng)前線程執(zhí)行的位置,從而當(dāng)線程被切換回來(lái)的時(shí)候能夠知道該線程上次運(yùn)行到哪兒了。

    1.3. 程序計(jì)數(shù)器的特點(diǎn)

    1. 是一塊較小的存儲(chǔ)空間
    2. 線程私有。每條線程都有一個(gè)程序計(jì)數(shù)器。
    3. 是唯一一個(gè)不會(huì)出現(xiàn)OutOfMemoryError的內(nèi)存區(qū)域。
    4. 生命周期隨著線程的創(chuàng)建而創(chuàng)建,隨著線程的結(jié)束而死亡。

    2. Java虛擬機(jī)棧(JVM Stack)

    2.1. 什么是Java虛擬機(jī)棧?

    Java虛擬機(jī)棧是描述Java方法運(yùn)行過(guò)程的內(nèi)存模型。
    Java虛擬機(jī)棧會(huì)為每一個(gè)即將運(yùn)行的Java方法創(chuàng)建一塊叫做“棧幀”的區(qū)域,這塊區(qū)域用于存儲(chǔ)該方法在運(yùn)行過(guò)程中所需要的一些信息,這些信息包括:

    1. 局部變量表
      存放基本數(shù)據(jù)類型變量、引用類型的變量、returnAddress類型的變量。
    2. 操作數(shù)棧
    3. 動(dòng)態(tài)鏈接
    4. 方法出口信息

    當(dāng)一個(gè)方法即將被運(yùn)行時(shí),Java虛擬機(jī)棧首先會(huì)在Java虛擬機(jī)棧中為該方法創(chuàng)建一塊“棧幀”,棧幀中包含局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口信息等。當(dāng)方法在運(yùn)行過(guò)程中需要?jiǎng)?chuàng)建局部變量時(shí),就將局部變量的值存入棧幀的局部變量表中。
    當(dāng)這個(gè)方法執(zhí)行完畢后,這個(gè)方法所對(duì)應(yīng)的棧幀將會(huì)出棧,并釋放內(nèi)存空間。

    注意:人們常說(shuō),Java的內(nèi)存空間分為“棧”和“堆”,棧中存放局部變量,堆中存放對(duì)象。
    這句話不完全正確!這里的“堆”可以這么理解,但這里的“棧”只代表了Java虛擬機(jī)棧中的局部變量表部分。真正的Java虛擬機(jī)棧是由一個(gè)個(gè)棧幀組成,而每個(gè)棧幀中都擁有:局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口信息。

    2.2. Java虛擬機(jī)棧的特點(diǎn)

    1. 局部變量表的創(chuàng)建是在方法被執(zhí)行的時(shí)候,隨著棧幀的創(chuàng)建而創(chuàng)建。而且,局部變量表的大小在編譯時(shí)期就確定下來(lái)了,在創(chuàng)建的時(shí)候只需分配事先規(guī)定好的大小即可。此外,在方法運(yùn)行的過(guò)程中局部變量表的大小是不會(huì)發(fā)生改變的。
    2. Java虛擬機(jī)棧會(huì)出現(xiàn)兩種異常:StackOverFlowError和OutOfMemoryError。
      a) StackOverFlowError:
      若Java虛擬機(jī)棧的內(nèi)存大小不允許動(dòng)態(tài)擴(kuò)展,那么當(dāng)線程請(qǐng)求棧的深度超過(guò)當(dāng)前Java虛擬機(jī)棧的最大深度的時(shí)候,就拋出StackOverFlowError異常。
      b) OutOfMemoryError:
      若Java虛擬機(jī)棧的內(nèi)存大小允許動(dòng)態(tài)擴(kuò)展,且當(dāng)線程請(qǐng)求棧時(shí)內(nèi)存用完了,無(wú)法再動(dòng)態(tài)擴(kuò)展了,此時(shí)拋出OutOfMemoryError異常。
    3. Java虛擬機(jī)棧也是線程私有的,每個(gè)線程都有各自的Java虛擬機(jī)棧,而且隨著線程的創(chuàng)建而創(chuàng)建,隨著線程的死亡而死亡。

    注:StackOverFlowError和OutOfMemoryError的異同?
    StackOverFlowError表示當(dāng)前線程申請(qǐng)的棧超過(guò)了事先定好的棧的最大深度,但內(nèi)存空間可能還有很多。
    而OutOfMemoryError是指當(dāng)線程申請(qǐng)棧時(shí)發(fā)現(xiàn)棧已經(jīng)滿了,而且內(nèi)存也全都用光了。

    3. 本地方法棧

    3.1. 什么是本地方法棧?

    本地方法棧和Java虛擬機(jī)棧實(shí)現(xiàn)的功能類似,只不過(guò)本地方法區(qū)是本地方法運(yùn)行的內(nèi)存模型。

    本地方法被執(zhí)行的時(shí)候,在本地方法棧也會(huì)創(chuàng)建一個(gè)棧幀,用于存放該本地方法的局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、出口信息。

    方法執(zhí)行完畢后相應(yīng)的棧幀也會(huì)出棧并釋放內(nèi)存空間。

    也會(huì)拋出StackOverFlowError和OutOfMemoryError異常。

    4. 堆

    4.1. 什么是堆?

    堆是用來(lái)存放對(duì)象的內(nèi)存空間。
    幾乎所有的對(duì)象都存儲(chǔ)在堆中。

    4.2. 堆的特點(diǎn)

    1. 線程共享
      整個(gè)Java虛擬機(jī)只有一個(gè)堆,所有的線程都訪問(wèn)同一個(gè)堆。而程序計(jì)數(shù)器、Java虛擬機(jī)棧、本地方法棧都是一個(gè)線程對(duì)應(yīng)一個(gè)的。
    2. 在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建
    3. 垃圾回收的主要場(chǎng)所。
    4. 可以進(jìn)一步細(xì)分為:新生代、老年代。
      新生代又可被分為:Eden、From Survior、To Survior。
      不同的區(qū)域存放具有不同生命周期的對(duì)象。這樣可以根據(jù)不同的區(qū)域使用不同的垃圾回收算法,從而更具有針對(duì)性,從而更高效。
    5. 堆的大小既可以固定也可以擴(kuò)展,但主流的虛擬機(jī)堆的大小是可擴(kuò)展的,因此當(dāng)線程請(qǐng)求分配內(nèi)存,但堆已滿,且內(nèi)存已滿無(wú)法再擴(kuò)展時(shí),就拋出OutOfMemoryError。

    5. 方法區(qū)

    5.1. 什么是方法區(qū)?

    Java虛擬機(jī)規(guī)范中定義方法區(qū)是堆的一個(gè)邏輯部分。
    方法區(qū)中存放已經(jīng)被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等。

    5.2. 方法區(qū)的特點(diǎn)

    1. 線程共享
      方法區(qū)是堆的一個(gè)邏輯部分,因此和堆一樣,都是線程共享的。整個(gè)虛擬機(jī)中只有一個(gè)方法區(qū)。
    2. 永久代
      方法區(qū)中的信息一般需要長(zhǎng)期存在,而且它又是堆的邏輯分區(qū),因此用堆的劃分方法,我們把方法區(qū)稱為老年代。
    3. 內(nèi)存回收效率低
      方法區(qū)中的信息一般需要長(zhǎng)期存在,回收一遍內(nèi)存之后可能只有少量信息無(wú)效。
      對(duì)方法區(qū)的內(nèi)存回收的主要目標(biāo)是:對(duì)常量池的回收 和 對(duì)類型的卸載。
    4. Java虛擬機(jī)規(guī)范對(duì)方法區(qū)的要求比較寬松。
      和堆一樣,允許固定大小,也允許可擴(kuò)展的大小,還允許不實(shí)現(xiàn)垃圾回收。

    5.3. 什么是運(yùn)行時(shí)常量池?

    方法區(qū)中存放三種數(shù)據(jù):類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼。其中常量存儲(chǔ)在運(yùn)行時(shí)常量池中。

    我們一般在一個(gè)類中通過(guò)public static final來(lái)聲明一個(gè)常量。這個(gè)類被編譯后便生成Class文件,這個(gè)類的所有信息都存儲(chǔ)在這個(gè)class文件中。

    當(dāng)這個(gè)類被Java虛擬機(jī)加載后,class文件中的常量就存放在方法區(qū)的運(yùn)行時(shí)常量池中。而且在運(yùn)行期間,可以向常量池中添加新的常量。如:String類的intern()方法就能在運(yùn)行期間向常量池中添加字符串常量。

    當(dāng)運(yùn)行時(shí)常量池中的某些常量沒(méi)有被對(duì)象引用,同時(shí)也沒(méi)有被變量引用,那么就需要垃圾收集器回收。

    6. 直接內(nèi)存

    直接內(nèi)存是除Java虛擬機(jī)之外的內(nèi)存,但也有可能被Java使用。

    在NIO中引入了一種基于通道和緩沖的IO方式。它可以通過(guò)調(diào)用本地方法直接分配Java虛擬機(jī)之外的內(nèi)存,然后通過(guò)一個(gè)存儲(chǔ)在Java堆中的DirectByteBuffer對(duì)象直接操作該內(nèi)存,而無(wú)需先將外面內(nèi)存中的數(shù)據(jù)復(fù)制到堆中再操作,從而提升了數(shù)據(jù)操作的效率。

    直接內(nèi)存的大小不受Java虛擬機(jī)控制,但既然是內(nèi)存,當(dāng)內(nèi)存不足時(shí)就會(huì)拋出OOM異常。

    綜上所述

    1. Java虛擬機(jī)的內(nèi)存模型中一共有兩個(gè)“棧”,分別是:Java虛擬機(jī)棧和本地方法棧。
      兩個(gè)“棧”的功能類似,都是方法運(yùn)行過(guò)程的內(nèi)存模型。并且兩個(gè)“棧”內(nèi)部構(gòu)造相同,都是線程私有。
      只不過(guò)Java虛擬機(jī)棧描述的是Java方法運(yùn)行過(guò)程的內(nèi)存模型,而本地方法棧是描述Java本地方法運(yùn)行過(guò)程的內(nèi)存模型。
    2. Java虛擬機(jī)的內(nèi)存模型中一共有兩個(gè)“堆”,一個(gè)是原本的堆,一個(gè)是方法區(qū)。方法區(qū)本質(zhì)上是屬于堆的一個(gè)邏輯部分。堆中存放對(duì)象,方法區(qū)中存放類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯的代碼。
    3. 堆是Java虛擬機(jī)中最大的一塊內(nèi)存區(qū)域,也是垃圾收集器主要的工作區(qū)域。
    4. 程序計(jì)數(shù)器、Java虛擬機(jī)棧、本地方法棧是線程私有的,即每個(gè)線程都擁有各自的程序計(jì)數(shù)器、Java虛擬機(jī)棧、本地方法區(qū)。并且他們的生命周期和所屬的線程一樣。
      而堆、方法區(qū)是線程共享的,在Java虛擬機(jī)中只有一個(gè)堆、一個(gè)方法棧。并在JVM啟動(dòng)的時(shí)候就創(chuàng)建,JVM停止才銷(xiāo)毀。

      本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
      轉(zhuǎn)藏 分享 獻(xiàn)花(0

      0條評(píng)論

      發(fā)表

      請(qǐng)遵守用戶 評(píng)論公約

      類似文章 更多

      主站蜘蛛池模板: 一本色道久久综合狠狠躁| 另类国产精品一区二区| 日韩精品亚洲专在线电影| 2019久久久高清日本道| 又大又爽又硬的曰皮视频| 丁香婷婷激情俺也去俺来也| 精品无人乱码一区二区三区| 一本色道久久综合亚洲精品| 亚洲乱色熟女一区二区三区麻豆| 亚洲中文字幕无码中字| 97欧美精品系列一区二区| 国产一区二区在线影院| 色屁屁WWW免费看欧美激情| 人妻中文字幕精品一页| 国产迷姦播放在线观看| 亚洲综合无码精品一区二区三区| xxxx丰满少妇高潮| 人妻少妇456在线视频| 野花社区视频在线观看| 无套后入极品美女少妇| 又色又爽又黄的视频网站| 亚洲综合色AAA成人无码| 2020中文字字幕在线不卡| 日韩内射美女人妻一区二区三区| 白嫩少妇无套内谢视频| 久久精品A一国产成人免费网站| 日韩人妻无码精品久久| 天堂中文官网在线| 欧美日韩精品一区二区三区高清视频| 丁香五月激情综合色婷婷| 日本欧美大码a在线观看| 精品熟女少妇AV免费观看| 久女女热精品视频在线观看| 色窝窝无码一区二区三区| 第一亚洲中文久久精品无码| 国产高清一区二区不卡| 亚洲一区二区三区无码久久| 午夜不卡欧美AAAAAA在线观看| 少妇人妻偷人精品系列| 在线看片免费人成视频电影| 中文字幕无码免费久久|