JVM

一、Java 虛擬機(jī)的概念

所謂虛擬機(jī),就是一臺虛擬的機(jī)器,它是一款軟件,用來執(zhí)行一系列虛擬計算機(jī)指令。大體上虛擬機(jī)可以分為系統(tǒng)虛擬機(jī)和程序虛擬機(jī)。Virtual Box、VMWare 就屬于系統(tǒng)虛擬機(jī),它們完全是對物理計算機(jī)的仿真,提供了一個可運(yùn)行完整操作系統(tǒng)的軟件平臺。程序虛擬機(jī)的典型代表就是 Java 虛擬機(jī),它專門為執(zhí)行單個計算機(jī)程序而設(shè)計,在 Java 虛擬機(jī)中執(zhí)行的指令我們稱為 Java 字節(jié)碼指令。

二、Java 虛擬機(jī)的結(jié)構(gòu)

  1. 類加載子系統(tǒng)
    負(fù)責(zé)從文件系統(tǒng)或者網(wǎng)絡(luò)中加載 Class 信息,加載的信息存放在一塊稱之為方法區(qū)的內(nèi)存空間。

  2. 方法區(qū)
    存放類信息、常量信息、常量池信息,包括字符串字面量和數(shù)字常量等。

  3. Java 堆
    在 Java 虛擬機(jī)啟動的時候建立 Java 堆,它是 Java 程序最主要的內(nèi)存工作區(qū)域,幾乎所有的對象實(shí)例都存放到 Java 堆中,堆空間是所有線程共享。

  4. 直接內(nèi)存
    Java 的 NIO 庫允許 Java 程序使用直接內(nèi)存,從而提高性能,通常直接內(nèi)存的速度會優(yōu)于 Java 堆,讀寫頻繁的場合可能會考慮使用。

  5. Java 棧
    每個虛擬機(jī)線程都有一個私有的棧,一個線程的 Java 棧在線程創(chuàng)建的時候被創(chuàng)建,Java 棧中保存著局部變量,方法參數(shù),方法調(diào)用、返回值等。

  6. 本地方法棧
    本地方法棧與 Java 棧非常類似,最大不同是,本地方法棧用于本地方法調(diào)用,Java 虛擬機(jī)運(yùn)行 Java 直接調(diào)用本地方法(通常使用 C 編寫)。

  7. 垃圾收集系統(tǒng)

  8. PC(Program Counter) 寄存器
    PC 寄存器也是每個線程私有的空間,Java 虛擬機(jī)會為每個線程創(chuàng)建 PC 寄存器。在任意時刻,一個 Java 線程總在執(zhí)行一個方法,這個方法被稱為當(dāng)前方法,如果當(dāng)前方法不是本地方法,PC 寄存器就會執(zhí)行當(dāng)前正在被執(zhí)行的指令;如果是本地方法,則 PC 寄存器值為 undefined。寄存器存放如當(dāng)前執(zhí)行環(huán)境指針,程序計數(shù)器,操作棧指針,計算的變量指針等信息。

  9. 執(zhí)行引擎
    虛擬機(jī)最核心的組件就是執(zhí)行引擎了,它負(fù)責(zé)執(zhí)行虛擬機(jī)的字節(jié)碼。

堆、棧、方法區(qū)的區(qū)別與聯(lián)系:
堆解決的是數(shù)據(jù)存儲的問題,即數(shù)據(jù)怎么放,放在哪兒。
棧解決的是程序運(yùn)行的問題,即程序如何運(yùn)行,或者說如何處理數(shù)據(jù)。
方法區(qū)則是輔助堆棧的快永久區(qū)(Perm),解決堆棧信息的產(chǎn)生,是先決條件。

例如,我們創(chuàng)建一個新的對象 User。那么,User 類的一些信息(類信息、靜態(tài)信息都存在于方法區(qū)中);而 User 對象被實(shí)例化出來以后,被存儲到 Java 堆中,一塊內(nèi)存空間;當(dāng)我們?nèi)ナ褂玫臅r候,都是使用 User 對象引用,形如 User user = new User() 這里的 user 就是存放在 Java 棧中的,即 User 真實(shí)對象的一個引用。

根據(jù)垃圾回收機(jī)制的不同,Java 堆有可能擁有不同的結(jié)構(gòu)。最為常見的就是將整個 Java 堆分為新生代和老年代。其中新生代存放新生的或者年齡不大的對象,老年代則存放老年對象。新生代分為 Eden 區(qū)、s0 區(qū)、s1 區(qū),s0 區(qū)、s1 區(qū)是兩塊大小相等且可以互換角色的空間。

Java 棧一塊線程私有的內(nèi)存空間,棧一般由三部分組成:局部變量表、操作數(shù)棧和幀數(shù)據(jù)區(qū)。

Java 方法區(qū)和堆一樣,是一塊所有線程共享的內(nèi)存區(qū)域,它保存系統(tǒng)的類信息,比如類的字段、方法、常量池等。方法區(qū)的大小決定了系統(tǒng)可以保存多少個類,如果系統(tǒng)定義太多的類,會導(dǎo)致方法區(qū)溢出,虛擬機(jī)也會拋出內(nèi)存溢出錯誤。方法區(qū)可以理解為永久區(qū)(Perm)。

三、JVM 參數(shù)

  1. 堆分配參數(shù)
    -XX:+UseSerialGC:配置串行回收期
    -Xms:設(shè)置 Java 程序啟動時初始堆大小
    -Xmx:設(shè)置 Java 程序能獲得的最大堆大小
    -Xmn:設(shè)置新生代的大小。新生代大小一般會設(shè)置為整個堆空間的 1/3 到 1/4 左右。
    -XX:SurvivorRatio:設(shè)置新生代中 Eden 區(qū)域和 s0/s1 區(qū)域的比例。

四、垃圾回收及其算法

  1. 引用計數(shù)算法
    無法處理循環(huán)引用的情況,且每次進(jìn)行加減操作比較浪費(fèi)系統(tǒng)性能。

  2. 標(biāo)記-清除算法
    會產(chǎn)生空間碎片.

  3. 復(fù)制算法

  4. 標(biāo)記壓縮算法

五、垃圾收集器

  1. 串行垃圾收集器

  2. 并行垃圾收集器
    ParallelGC,吞吐量優(yōu)先收集器

  3. CMS 收集器

  4. G1 收集器

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • JVM內(nèi)存模型Java虛擬機(jī)(Java Virtual Machine=JVM)的內(nèi)存空間分為五個部分,分別是: ...
    光劍書架上的書閱讀 2,783評論 2 26
  • 內(nèi)存溢出和內(nèi)存泄漏的區(qū)別 內(nèi)存溢出:out of memory,是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,...
    Aimerwhy閱讀 808評論 0 1
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡(luò)上收集的一些資料的整理,因此不免有一些不準(zhǔn)確的地方,同時不同JDK版本的...
    高廣超閱讀 16,062評論 3 83
  • 秀才張葛今年二十有二了,為了方便趕考上個月借住到京城旁李家村的叔父家。 已經(jīng)連著幾天都陰云不開,昨個還下了場小雪,...
    GreenBear閱讀 469評論 0 1
  • 人常說:“愛能使心靈的創(chuàng)傷痊愈?!蔽疑钚牛簮鄣哪芰θQ于審美能力。 非暴力不是今天用了,明天就可以拋棄的權(quán)宜之計。...
    Lucky_ce60閱讀 1,038評論 0 0

友情鏈接更多精彩內(nèi)容