<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JVM 運(yùn)行時數(shù)據(jù)區(qū)詳解,寫得非常好!

          共 2861字,需瀏覽 6分鐘

           ·

          2020-07-27 19:19

          Java技術(shù)棧

          www.javastack.cn

          關(guān)注閱讀更多優(yōu)質(zhì)文章



          作者:小小木的博客
          www.cnblogs.com/wyc1994666/p/11795781.html


          在接下來的幾天想總結(jié)下,JVM相關(guān)的一些內(nèi)容,比如下面的這三個內(nèi)容算是比較核心知識點(diǎn)了

          1.運(yùn)行時數(shù)據(jù)區(qū)域: 在運(yùn)行時數(shù)據(jù)區(qū)里存儲類Class文件元數(shù)據(jù)(方法區(qū)),對象和數(shù)組(堆),方法參數(shù)局部變量(棧)等。

          2.垃圾回收機(jī)制: java 語言的優(yōu)勢之一就是它的自動內(nèi)存管理,主要回收運(yùn)行時數(shù)據(jù)區(qū)域的堆內(nèi)存里的數(shù)據(jù)

          3.類加載機(jī)制: 虛擬機(jī)首先需要把編譯完成的字節(jié)碼文件通過類加載器來加載到運(yùn)行時數(shù)據(jù)區(qū)域

          一個段Java代碼的生命周期都會少不了上圖這幾個步驟,也就是Java代碼首先會被編譯成字節(jié)碼文件,之后被類加載器加載到運(yùn)行時數(shù)據(jù)區(qū)域,以及運(yùn)行,垃圾收集器回收對象等等。

          但今天我想介紹第一個知識點(diǎn)《運(yùn)行時數(shù)據(jù)區(qū)域》

          1 運(yùn)行時數(shù)據(jù)區(qū)

          Java虛擬機(jī)定義了一系列邏輯數(shù)據(jù)區(qū)域,有些是隨著虛擬機(jī)的啟動而創(chuàng)建,虛擬機(jī)的關(guān)閉而銷毀。還有一部分是隨著線程生命周期創(chuàng)建銷毀的。

          我們有必要深入了解這塊的內(nèi)容,因?yàn)樗鼘Q定服務(wù)器性能,首先我們需要對整個運(yùn)行時區(qū)域由整體的認(rèn)識并且了解了每個區(qū)域的生命周期以及作用之后才能通過相應(yīng)的調(diào)參來提升系統(tǒng)性能。除此之外還有助于快速定位虛擬機(jī)的相關(guān)Error.

          邏輯上可以劃出一下6個區(qū)域分別是

          1.1 PC寄存器

          全名叫做 Program Counter Register 既然是叫做寄存器了那么肯定是需要存東西,那到底存的是什呢?

          由于JVM同時可以處理多個線程所以就涉及到一些線程調(diào)度,當(dāng)cpu暫停運(yùn)行線程A把時間片讓給線程B的時候我們需要保存線程A被暫停執(zhí)行前的一些現(xiàn)場狀態(tài),需要記錄當(dāng)前執(zhí)行到那一行字節(jié)碼了,所以具備保存現(xiàn)場的功能。

          每條線程都有自己的pc寄存器,在任意時刻虛擬機(jī)只會執(zhí)行一個方法,如果執(zhí)行的是方法不是native方法 pc寄存器則保存指向當(dāng)前執(zhí)行字節(jié)碼的指令地址,如果執(zhí)行的是native方法 pc寄存器會保存undefined。

          1.2 java虛擬機(jī)棧

          虛擬機(jī)棧也是每條線程私有的區(qū)域,里頭存儲棧幀(Frame),后面會重點(diǎn)介紹棧幀算是重點(diǎn)內(nèi)容。方法的調(diào)用與返回基于棧幀來實(shí)現(xiàn)的。

          1.3 虛擬機(jī)堆

          在Java虛擬機(jī)中堆是所有線程都可以共享的內(nèi)存區(qū)域,是存放所有類實(shí)例和數(shù)組對象的地方。在虛擬機(jī)啟動就根據(jù)相關(guān)堆參數(shù),創(chuàng)建堆,他也是垃圾收集器工作的主要區(qū)域。

          堆內(nèi)存里的對象不會被顯式的回收,而是由垃圾回收器回收,為了配合垃圾收集器的特性我們可以把堆分為年輕代和老年代。

          年輕代又分了Eden和survivor區(qū),主要是為了配合垃圾回收算法而這么搞得。

          1.4 方法區(qū)和運(yùn)行時常量池

          在Java虛擬機(jī)中 方法區(qū)是可提供各個線程共享的運(yùn)行時內(nèi)存區(qū)域,它存儲了每一個類的結(jié)構(gòu)信息,例如運(yùn)行時常量池,字段和方法數(shù)據(jù),構(gòu)造函數(shù)和普通函數(shù)的字節(jié)碼內(nèi)容,一句話總結(jié)就是存儲元數(shù)據(jù)地方

          運(yùn)行時常量池是class文件中每個類或接口常量池表的表示形式。它包括了若干不同的常量,比如 從編譯期可知的數(shù)值字面量到運(yùn)行時才能解析獲得的方法或字段引用等等。

          創(chuàng)建時機(jī)

          每個運(yùn)行時常量池都在Java虛擬機(jī)的方法區(qū)中分配,在加載類和接口到虛擬機(jī)之后創(chuàng)建對應(yīng)的運(yùn)行時常量池

          1.5 本地方法棧

          如果我們想再Java底層里調(diào)用別的語言代碼的話就需要用到別的方法棧了,比如Java虛擬機(jī)的實(shí)現(xiàn)會用到傳統(tǒng)的棧(C stack)來調(diào)用native方法,這個就是本地方法棧的應(yīng)用,當(dāng)然這個不是必須實(shí)現(xiàn)的,完全取決于虛擬機(jī)的實(shí)現(xiàn)。

          2 棧幀:

          首先看下棧幀在虛擬機(jī)內(nèi)存中在什么位置,

          棧幀是用來存儲數(shù)據(jù)和部分過程結(jié)果的數(shù)據(jù)結(jié)構(gòu),同時也用來處理動態(tài)鏈接,方法返回,異常分派等工作。

          棧幀的生命周期是跟方法一致的,隨著方法的調(diào)用而創(chuàng)建,方法的結(jié)束或者異常而銷毀。

          每個棧幀都由局部變量表,操作數(shù)棧,動態(tài)鏈接組成的

          2.1 局部變量表 (Local variable)

          每個棧幀內(nèi)部都包含一組稱為局部變量表的列表,變量表的長度在編譯期決定。另外關(guān)注公眾號Java技術(shù)棧在后臺回復(fù)JVM獲取一份46頁的JVM調(diào)優(yōu)教程。

          一個局部變量可以存儲一個基本數(shù)據(jù)類型或一個對象引用(referance),returnAddress的數(shù)據(jù)。存儲long或double需要兩個局部變量才能存儲。

          當(dāng)虛擬機(jī)要使用局部變量表里的數(shù)據(jù)時通過索引來定位,默認(rèn)從0開始,由于long和double占用兩個局部變量所以它的索引較特殊,取決于最小的那個值,比如某個long類型數(shù)據(jù)在索引n和n+1里存儲了,那么它對應(yīng)的索引值就是n.
          虛擬機(jī)通過局部變量表來完成方法調(diào)用時的參數(shù)傳遞。如果是類方法,它的參數(shù)依次從0開始的位置傳遞到局部變量表,如果是實(shí)例方法則第0位置存儲所在對象的引用(this),從1開始傳遞參數(shù)。

          2.2 操作數(shù)棧 (Operating Stack)

          操作數(shù)棧是屬于棧幀中的棧,其實(shí)它的全名叫做當(dāng)前棧幀的初操作數(shù)棧。棧,棧幀,操作數(shù)棧的關(guān)系需要梳理清楚:

          • 棧:是虛擬機(jī)運(yùn)行時數(shù)據(jù)區(qū)的一個邏輯區(qū)域,里面存儲了一個個棧幀。

          • 棧幀:棧幀代表一個方法的整個生命周期,里頭存儲了局部變量表,操作數(shù)棧,動態(tài)鏈接

          • 操作數(shù)棧: 剛剛創(chuàng)建時操作數(shù)棧是空的。虛擬機(jī)提供一些指令從局部變量表把一些常量或者變量值加載到操作數(shù)棧,也提供了從操作數(shù)棧取走數(shù)據(jù)的指令。
            調(diào)用方法時操作數(shù)棧用來準(zhǔn)備調(diào)用方法參數(shù)以及接受方法的返回結(jié)果。

          2.3 動態(tài)鏈接 (Dynamic Linking)。

          動態(tài)鏈接是用來完成運(yùn)行時綁定操作的。在棧幀中有一個指向常量池的當(dāng)前類的一個引用。在class文件里一個方法要是調(diào)用其他方法或者方法其他成員變量,則需要通過符號引用來表示。

          • 動態(tài)鏈接的作用就是將符號引用轉(zhuǎn)換為直接引用。

          • 類加載的過程中將要解析尚未被解析的符號引用,并且把對變量的訪問轉(zhuǎn)換為正確的偏移量。

          最近熱文:
          1、盤點(diǎn) 6 個被淘汰的 Java 技術(shù),曾經(jīng)風(fēng)光過!
          2、Spring Boot 如何快速集成 Redis?
          3、Spring Boot Redis 實(shí)現(xiàn)分布式鎖,真香!
          4、Mybatis 框架 SQL 注入攻擊的 3 種方式!
          5、Java 14 祭出神器,Lombok 被干掉了?
          6、Java 14 祭出增強(qiáng)版 switch,真香??!
          7、Spring Boot 2.3 優(yōu)雅關(guān)閉新姿勢,真香!
          8、Spring Boot 干掉了 Maven 擁抱 Gradle!
          9、公司來了個新同事不會用 Lombok!
          10、Spring Cloud 2020 版本重大變革!
          掃碼關(guān)注Java技術(shù)棧公眾號閱讀更多干貨。

          點(diǎn)擊「閱讀原文」獲取面試題大全~

          瀏覽 48
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩电影一区二区三区不卡 | 日韩高清无码电影 | 日韩av在线小说 日韩av在线直播 | a在线级电影网站 | 免费无码婬片69视频软件+1 |