JVM學(xué)習(xí)(一些重要知識(shí)點(diǎn))

https://www.cnblogs.com/chanshuyi/p/jvm_serial_04_from_source_code_to_machine_code.html

1、編譯器和解釋器,源代碼到字節(jié)碼再到機(jī)器碼

編譯器種類(lèi).png
JIT編譯器(Just In Time Compiler)

當(dāng)源代碼轉(zhuǎn)化為字節(jié)碼之后,其實(shí)要運(yùn)行程序,有兩種選擇。一種是使用 Java 解釋器解釋執(zhí)行字節(jié)碼,另一種則是使用 JIT 編譯器將字節(jié)碼轉(zhuǎn)化為本地機(jī)器代碼。
這兩種方式的區(qū)別在于,前者啟動(dòng)速度快但運(yùn)行速度慢,而后者啟動(dòng)速度慢但運(yùn)行速度快。至于為什么會(huì)這樣,其原因很簡(jiǎn)單。因?yàn)榻忉屍鞑恍枰?JIT 編譯器一樣,將所有字節(jié)碼都轉(zhuǎn)化為機(jī)器碼,自然就少去了優(yōu)化的時(shí)間。而當(dāng) JIT 編譯器完成第一次編譯后,其會(huì)將字節(jié)碼對(duì)應(yīng)的機(jī)器碼保存下來(lái),下次可以直接使用。而我們知道,機(jī)器碼的運(yùn)行效率肯定是高于 Java 解釋器的。所以在實(shí)際情況中,為了運(yùn)行速度以及效率,我們通常采用兩者相結(jié)合的方式進(jìn)行 Java 代碼的編譯執(zhí)行。

image.png

在 JVM 中有三個(gè)非常重要的編譯器,它們分別是:前端編譯器、JIT 編譯器AOT 編譯器。
前端編譯器,最常見(jiàn)的就是我們的 javac 編譯器,其將 Java 源代碼編譯為 Java 字節(jié)碼文件。JIT 即時(shí)編譯器,最常見(jiàn)的是 HotSpot 虛擬機(jī)中的 Client Compiler 和 Server Compiler,其將 Java 字節(jié)碼編譯為本地機(jī)器代碼。而 AOT 編譯器則能將源代碼直接編譯為本地機(jī)器碼。這三種編譯器的編譯速度和編譯質(zhì)量如下:
編譯速度上,解釋執(zhí)行 > AOT 編譯器 > JIT 編譯器。
編譯質(zhì)量上,JIT 編譯器 > AOT 編譯器 > 解釋執(zhí)行。
而在 JVM 中,通過(guò)這幾種不同方式的配合,使得 JVM 的編譯質(zhì)量和運(yùn)行速度達(dá)到最優(yōu)的狀態(tài)。

2、字節(jié)碼結(jié)構(gòu)

https://www.cnblogs.com/chanshuyi/p/jvm_serial_05_jvm_bytecode_analysis.html

Class文件字節(jié)碼結(jié)構(gòu)組織示意圖.png

3、類(lèi)加載執(zhí)行步驟

JVM 虛擬機(jī)執(zhí)行 class 字節(jié)碼的過(guò)程可以分為七個(gè)階段:加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用、卸載。

4、JVM參數(shù)設(shè)置

https://blog.csdn.net/longgeqiaojie304/article/details/93851827

    【1】Boolean類(lèi)型XX參數(shù)
        公式:-XX:+ 或者-XX:- 某個(gè)屬性值(+表示開(kāi)啟,-表示關(guān)閉)
        案例:   
        1)是否打印GC收集細(xì)節(jié)
               -XX:+PrintGCDetails
               -XX:-PrintGCDetails
        2)是否使用串行垃圾收集器
               -XX:+UseSerialGC
               -XX:-UserSerialGC

    【2】KV設(shè)值類(lèi)型
           公式:-XX: key(屬性)= value(屬性值)
           案例:
           查看-XX:MetaspaceSize=默認(rèn)值大小

    【3】如何解釋-Xms和-Xmx參數(shù)屬于XX參數(shù)
      -Xms和-Xmx兩個(gè)經(jīng)典參數(shù)看起既不像Boolean類(lèi)型XX參數(shù),也不像KV設(shè)值類(lèi)型XX參數(shù)。那為什么-Xms和-Xmx又屬于XX參數(shù)?
       -Xms = -XX:InitialHeapSize
       -Xmx = -XX:MaxHeapSize

5、JVM堆內(nèi)存分配

https://my.oschina.net/u/2984281/blog/784027

Jvm區(qū)域總體分兩類(lèi),heap區(qū)非heap區(qū)。heap區(qū)又分:Eden Space(伊甸園)、Survivor Space(幸存者區(qū))、Tenured Gen(老年代-養(yǎng)老區(qū))
年輕代(Young Gen):年輕代主要存放新創(chuàng)建的對(duì)象,內(nèi)存大小相對(duì)會(huì)比較小,垃圾回收會(huì)比較頻繁,年輕代分成1個(gè)Eden Space和2個(gè)Suvivor Space
年老代(Tenured Gen):年老代主要存放JVM認(rèn)為生命周期比較長(zhǎng)的對(duì)象(經(jīng)過(guò)幾次的Young Gen的垃圾回收后仍然存在),內(nèi)存大小相對(duì)會(huì)比較大,垃圾回收也相對(duì)沒(méi)有那么頻繁(譬如可能幾個(gè)小時(shí)一次)
持久代(Perm Gen):持久代主要存放類(lèi)定義、字節(jié)碼和常量等很少會(huì)變更的信息

6、重載

在Java語(yǔ)言中,字段是無(wú)法重載的。兩個(gè)字段的數(shù)據(jù)類(lèi)型、修飾符不管是否相同,都必須使用不一樣的名稱(chēng);
在Class文件中,如果兩個(gè)字段的描述符不一致,那字段重名就是合法的。

Java語(yǔ)言中,要重載一個(gè)方法,除了要與原方法具有相同的簡(jiǎn)單名稱(chēng)之外,還要求必須擁有與原方法不同的特征簽名。特征簽名是指,一個(gè)方法中各個(gè)參數(shù)在常量池中的字段符號(hào)引用的集合。也就是因?yàn)?code>返回值不會(huì)包含在特征簽名中,因此Java語(yǔ)言里面是無(wú)法僅僅依靠返回值的不同來(lái)對(duì)一個(gè)已有方法進(jìn)行重載的;
而在Class文件中,特征簽名的范圍更大,只要描述符不是完全一致的兩個(gè)方法也可以共存。也就是說(shuō),如果兩個(gè)方法有相同的名稱(chēng)和特征簽名,但返回值不同,那么也是可以合法共存于同一個(gè)Class文件中的。

7、Class文件中的Code屬性

Java程序方法體中的代碼經(jīng)過(guò)Javac編譯器處理之后,最終變?yōu)樽止?jié)碼指令存儲(chǔ)在Code屬性內(nèi)。Code屬性出現(xiàn)在方法表的屬性集合中,但不是所有的方法表都必須存在這個(gè)屬性,譬如接口或者抽象類(lèi)中的方法。

任何實(shí)例方法中(static方法除外),都可以通過(guò)“this”關(guān)鍵字訪問(wèn)到此方法所屬的對(duì)象。其實(shí)現(xiàn)是:通過(guò)在javac編譯器編譯的時(shí)候把對(duì)this關(guān)鍵字的訪問(wèn)轉(zhuǎn)變?yōu)?code>對(duì)一個(gè)普通方法參數(shù)的訪問(wèn),然后在虛擬機(jī)調(diào)用實(shí)例方法時(shí)自動(dòng)傳入此參數(shù)。因此在實(shí)例方法的局部變量表中至少會(huì)存在一個(gè)指向當(dāng)前對(duì)象實(shí)例的局部變量,局部變量表中也會(huì)預(yù)留出第一個(gè)Slot位來(lái)存放對(duì)象實(shí)例的引用,方法參數(shù)值從1開(kāi)始計(jì)算。

8、Full GC和Minor GC、Major GC

https://www.cnblogs.com/chanshuyi/p/jvm_serial_10_gc_type.html

從年輕代空間回收內(nèi)存被稱(chēng)為 Minor GC,有時(shí)候也稱(chēng)之為 Young GC。對(duì)于 Minor GC,你需要知道的一些點(diǎn):

(1)當(dāng) JVM 無(wú)法為一個(gè)新的對(duì)象分配空間時(shí)會(huì)觸發(fā) Minor GC,比如當(dāng) Eden 區(qū)滿了。所以 Eden 區(qū)越小,越頻繁執(zhí)行 Minor GC。
(2)當(dāng)年輕代中的 Eden 區(qū)分配滿的時(shí)候,年輕代中的部分對(duì)象會(huì)晉升到老年代,所以 Minor GC 后老年代的占用量通常會(huì)有所升高。
質(zhì)疑常規(guī)的認(rèn)知,所有的 Minor GC 都會(huì)觸發(fā) Stop-The-World,停止應(yīng)用程序的線程。對(duì)于大部分應(yīng)用程序,停頓導(dǎo)致的延遲都是可以忽略不計(jì)的,因?yàn)榇蟛糠?Eden 區(qū)中的對(duì)象都能被認(rèn)為是垃圾,永遠(yuǎn)也不會(huì)被復(fù)制到 Survivor 區(qū)或者老年代空間。如果情況相反,即 Eden 區(qū)大部分新生對(duì)象不符合 GC 條件(即他們不被垃圾回收器收集),那么 Minor GC 執(zhí)行時(shí)暫停的時(shí)間將會(huì)長(zhǎng)很多(因?yàn)樗麄円狫VM要將他們復(fù)制到 Survivor 區(qū)或老年代)。

從老年代空間回收內(nèi)存被稱(chēng)為 Major GC,有時(shí)候也稱(chēng)之為 Old GC。
許多 Major GC 是由 Minor GC 觸發(fā)的,所以很多情況下將這兩種 GC 分離是不太可能的。

Minor GC 作用于年輕代Major GC 作用于老年代。 分配對(duì)象內(nèi)存時(shí)發(fā)現(xiàn)內(nèi)存不夠,觸發(fā) Minor GC。Minor GC 會(huì)將對(duì)象移到老年代中,如果此時(shí)老年代空間不夠,那么觸發(fā) Major GC。因此才會(huì)說(shuō),許多 Major GC 是由 Minor GC 引起的。

Full GC 是清理整個(gè)堆空間 —— 包括年輕代、老年代和永久代(如果有的話)。因此 Full GC 可以說(shuō)是 Minor GC 和 Major GC 的結(jié)合。

當(dāng)準(zhǔn)備要觸發(fā)一次 Minor GC 時(shí),如果發(fā)現(xiàn)年輕代的剩余空間比以往晉升的空間小,則不會(huì)觸發(fā) Minor GC 而是轉(zhuǎn)為觸發(fā) Full GC。因?yàn)镴VM此時(shí)認(rèn)為:之前這么大空間的時(shí)候已經(jīng)發(fā)生對(duì)象晉升了,那現(xiàn)在剩余空間更小了,那么很大概率上也會(huì)發(fā)生對(duì)象晉升。既然如此,那么我就直接幫你把事情給做了吧,直接來(lái)一次 Full GC,整理一下老年代和年輕代的空間。

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

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

  • Java 虛擬機(jī)(Java virtual machine,JVM)是運(yùn)行 Java 程序必不可少的機(jī)制。JVM實(shí)...
    Rick617閱讀 963評(píng)論 0 0
  • 《深入理解Java虛擬機(jī)》筆記_第一遍 先取看完這本書(shū)(JVM)后必須掌握的部分。 第一部分 走近 Java 從傳...
    xiaogmail閱讀 5,476評(píng)論 1 34
  • 內(nèi)存溢出和內(nèi)存泄漏的區(qū)別 內(nèi)存溢出:out of memory,是指程序在申請(qǐng)內(nèi)存時(shí),沒(méi)有足夠的內(nèi)存空間供其使用,...
    Aimerwhy閱讀 807評(píng)論 0 1
  • JVM(Java Virtual Machine,Java虛擬機(jī)) Java程序的跨平臺(tái)特性主要是指字節(jié)碼文件可以...
    uknownothi_8742閱讀 356評(píng)論 0 0
  • 工作之余,想總結(jié)一下JVM相關(guān)知識(shí)。 Java運(yùn)行時(shí)數(shù)據(jù)區(qū): Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中會(huì)將其管理的...
    Huang遠(yuǎn)閱讀 683評(píng)論 0 2

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