一篇文章带你快速理解JVM运行时数据区 、程序计数器详解 (手画详图)值得收藏!!!
受多種情況的影響,又開始看JVM 方面的知識(shí)。
1、Java 實(shí)在過于內(nèi)卷,沒法不往深了學(xué)。
2、面試題問的多,被迫學(xué)習(xí)。
3、純粹的好奇。
很喜歡一句話:“八小時(shí)內(nèi)謀生活,八小時(shí)外謀發(fā)展。”
— 望別日與君相見時(shí),君已有所成。
共勉
地點(diǎn):湖南一個(gè)小城市邵陽(yáng)
作者:博主
一篇文章帶你快速理解JVM運(yùn)行時(shí)數(shù)據(jù)區(qū) 、程序計(jì)數(shù)器詳解詳解 (手畫詳圖)值得收藏!!!
- 一、運(yùn)行時(shí)數(shù)據(jù)區(qū)
- 圖示:
- 運(yùn)行時(shí)數(shù)據(jù)區(qū)的完整圖:
- 運(yùn)行時(shí)數(shù)據(jù)區(qū)概述:
- 二、程序計(jì)數(shù)器(Program Counter)
- 概述:
- 代碼講解
- 使用PC寄存器存儲(chǔ)字節(jié)碼指令地址有什么用呢?
- 那么 PC寄存器為什么被設(shè)定為私有的?(圖解)
- 自言自語(yǔ):
一、運(yùn)行時(shí)數(shù)據(jù)區(qū)
圖示:
補(bǔ)充一個(gè)點(diǎn): 在運(yùn)行時(shí)數(shù)據(jù)區(qū)中,灰色的為單獨(dú)線程私有的,紅色的為多個(gè)線程共享的,即:
- 每個(gè)線程:獨(dú)立包括程序計(jì)數(shù)器、棧、本地棧。
- 線程間共享:堆、堆外內(nèi)存(永久代或元空間、代碼緩存)
運(yùn)行時(shí)數(shù)據(jù)區(qū)的完整圖:
不同的JVM對(duì)于內(nèi)存的劃分方式和管理機(jī)制存在著部分差異。這里給出一張完整的運(yùn)行時(shí)數(shù)據(jù)區(qū)圖。🤱
看完上面的兩張圖,我想應(yīng)該對(duì)JVM中所謂的運(yùn)行時(shí)數(shù)據(jù)區(qū)有個(gè)大概印象了吧。下面👇會(huì)給大家再給大家?guī)硪恍┐致缘闹v解哈。
運(yùn)行時(shí)數(shù)據(jù)區(qū)概述:
當(dāng)我們通過前面的:類的加載-> 驗(yàn)證 -> 準(zhǔn)備 -> 解析 -> 初始化 這幾個(gè)階段完成后,就會(huì)用到執(zhí)行引擎對(duì)我們的類進(jìn)行使用,同時(shí)執(zhí)行引擎將會(huì)使用到我們運(yùn)行時(shí)數(shù)據(jù)區(qū) 🤸?♂?
運(yùn)行時(shí)數(shù)據(jù)區(qū),Runtime Data Area,用于保存java程序運(yùn)行過程中需要用到的數(shù)據(jù)和相關(guān)信息;經(jīng)常說的把數(shù)據(jù)讀到內(nèi)存,包括類加載之后的信息,從磁盤讀取文件信息等。即:Java虛擬機(jī)在執(zhí)行Java程序的過程中,會(huì)將涉及的數(shù)據(jù)劃分到不同的內(nèi)存區(qū)域去管理。
課間休息會(huì)
二、程序計(jì)數(shù)器(Program Counter)
概述:
程序計(jì)數(shù)器是用于存放下一條指令所在單元的地址的地方。
當(dāng)執(zhí)行一條指令時(shí),首先需要根據(jù)PC中存放的指令地址,將指令由內(nèi)存取到指令寄存器中,此過程稱為“取指令”。與此同時(shí),PC中的地址或自動(dòng)加1或由轉(zhuǎn)移指針給出下一條指令的地址。此后經(jīng)過分析指令,執(zhí)行指令。完成第一條指令的執(zhí)行,而后根據(jù)PC取出第二條指令的地址,如此循環(huán),執(zhí)行每一條指令。
JVM中的PC寄存器是對(duì)物理PC寄存器的一種抽象模擬。
程序計(jì)數(shù)器是線程私有內(nèi)存,是唯一一個(gè)在java虛擬機(jī)規(guī)范中沒有規(guī)定任何OutOfMemoryError的區(qū)域。
代碼講解
JAVA代碼編譯后的字節(jié)碼在未經(jīng)過JIT(實(shí)時(shí)編譯器)編譯前,其執(zhí)行方式是通過“字節(jié)碼解釋器”進(jìn)行解釋執(zhí)行。**簡(jiǎn)單的工作原理為解釋器讀取裝載入內(nèi)存的字節(jié)碼,按照順序讀取字節(jié)碼指令。**讀取一個(gè)指令后,將該指令“翻譯”成固定的操作,并根據(jù)這些操作進(jìn)行分支、循環(huán)、跳轉(zhuǎn)等流程。
例如:
使用javap -c -verbose ClassCode.class 命令反編譯出來結(jié)果為:
從上面的描述中,可能會(huì)產(chǎn)生程序計(jì)數(shù)器是否是多余的疑問。
因?yàn)檠刂噶畹捻樞驁?zhí)行下去,即使是分支跳轉(zhuǎn)這樣的流程,跳轉(zhuǎn)到指定的指令處按順序繼續(xù)執(zhí)行是完全能夠保證程序的執(zhí)行順序的。假設(shè)程序永遠(yuǎn)只有一個(gè)線程,這個(gè)疑問沒有任何問題,也就是說并不需要程序計(jì)數(shù)器。但實(shí)際上程序是通過多個(gè)線程協(xié)同合作執(zhí)行的。
首先我們要搞清楚JVM的多線程實(shí)現(xiàn)方式。JVM的多線程是通過CPU時(shí)間片輪轉(zhuǎn)(即線程輪流切換并分配處理器執(zhí)行時(shí)間)算法來實(shí)現(xiàn)的。也就是說,某個(gè)線程在執(zhí)行過程中可能會(huì)因?yàn)闀r(shí)間片耗盡而被掛起,而另一個(gè)線程獲取到時(shí)間片開始執(zhí)行。當(dāng)被掛起的線程重新獲取到時(shí)間片的時(shí)候,它要想從被掛起的地方繼續(xù)執(zhí)行,就必須知道它上次執(zhí)行到哪個(gè)位置,在JVM中,通過程序計(jì)數(shù)器來記錄某個(gè)線程的字節(jié)碼執(zhí)行位置。因此,程序計(jì)數(shù)器是具備線程隔離的特性,也就是說,每個(gè)線程工作時(shí)都有屬于自己的獨(dú)立計(jì)數(shù)器。 即私有性,每個(gè)線程都擁有私有的程序計(jì)數(shù)器
使用PC寄存器存儲(chǔ)字節(jié)碼指令地址有什么用呢?
其實(shí)在上一段文字中已經(jīng)寫了,這里寫個(gè)縮句哈。
因?yàn)镃PU需要不停的切換各個(gè)線程,這時(shí)候切換回來以后,就得知道接著從哪開始繼續(xù)執(zhí)行。
JVM的字節(jié)碼解釋器就需要通過改變PC寄存器的值來明確下一條應(yīng)該執(zhí)行什么樣的字節(jié)碼指令。
那么 PC寄存器為什么被設(shè)定為私有的?(圖解)
由于CPU時(shí)間片輪限制,眾多線程在并發(fā)執(zhí)行過程中,任何一個(gè)確定的時(shí)刻,一個(gè)處理器或者多核處理器中的一個(gè)內(nèi)核,只會(huì)執(zhí)行某個(gè)線程中的一條指令。
這樣必然導(dǎo)致經(jīng)常中斷或恢復(fù),如何保證分毫無差呢?每個(gè)線程在創(chuàng)建后,都會(huì)產(chǎn)生自己的程序計(jì)數(shù)器和棧幀,程序計(jì)數(shù)器在各個(gè)線程之間互不影響。
還是決定手畫幾張圖來幫助大家來理解記憶:
我想看完這個(gè)圖,大家對(duì)pc 程序計(jì)數(shù)器 為什么是私有是有個(gè)大概的理解了吧。
自言自語(yǔ):
更多的文章在后面拉,還會(huì)有的,路還長(zhǎng)勒。
人生路上選擇眾多,但不要害怕選擇,那都是人生寶貴的財(cái)富,
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的一篇文章带你快速理解JVM运行时数据区 、程序计数器详解 (手画详图)值得收藏!!!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JVM-虚拟机栈详解 附面试高频题 (手
- 下一篇: 史上最详细Docker安装最新版Mini