JVM的特性,透過程式碼來揭秘執行時資料區
執行時資料區
之前學習類載入器的時候,最後放出了一張圖,再來回顧一下
類載入器就是把位元組碼檔案載入到執行時資料區裡面的一個機制,載入到執行時資料區之後呢,又發生了什麼?
接下來我們就來看看。這就是JVM執行時資料區:
而黃色區,會被稱為棧。
堆和棧的根本作用,就是用來存放資料用的。
先上一段程式碼:
/** * 作者:LKP * 時間:2018/11/7 */
class Person{ String name = new String("1234");
public Person(String name) {
this.name = name; }
public void sayHello(){ System.out.println("hello:"+name); } }
public class AppTest {
public static void main(String[] args) { Person person = new Person("張三"); person.sayHello(); } }
後面的分析都是建立在這個AppTest類的。
堆:
堆是用來幹嘛的?
就好比前面的程式,new Person("張三"); 它儲存的地方就是在堆裡面。
什麼是OutOfMemoryError異常,可能有些人沒有接觸過,我也是再一次面試當中遇到的,之後去查閱過相關資料。
現在我們來模擬一下OutOfMemoryError異常:
/** * 作者:LKP * 時間:2018/11/7 */
public class HeapOOM {
//-Xms64m -Xmx128m public static void main(String[] args) { String[] str = new String[400000000]; System.out.println(str.length); } }
啟動引數設定為:-Xms64m -Xmx128m,然後執行:
這種異常就是OutOfMemoryError異常,記憶體溢位了,造成的原因很多種,有興趣的小夥伴可以去了解一下。
方法區:
之前說到了類載入載入,並且執行,我們怎麼樣執行呢?這就跟方法區有關係了。
類資訊:它是對一個類的描述
上面兩條sql語句一樣,第一條是它的表結構,這些就是表結構的資訊。類資訊(MetaInfo)就是後設資料,描述我們一個類的資訊的。
執行時常量池:它的作用是存放我們一些常量和靜態變數的
比如:
靜態變數:static int NAME = "張三";
常量:final .....
這些都是存放在執行時常量池的。
編譯器有兩個:一個是靜態編譯,一個是JIT。
JIT編譯:就是執行編譯。
靜態編譯:java編譯成class檔案
為什麼要有JIT編譯呢?那肯定是有它好處的:
看一下這段程式碼,他是熱點程式碼,就是需要頻繁去執行的
為了效率,JIT編譯會把位元組碼編譯為機器執行碼,這樣速度就大大提高了。
JIT的目的,就是把位元組碼>>>機器執行碼,把它存放在方法區裡面。
方法區呢,就是存放方法的地方,不過為了區分不同類的方法,也需要把類資訊也儲存進去,這樣才能區分不同類的相同方法。
程式計數器:
什麼是程式計數器?
程式計數器它就是讓我們程式按照我們的指定指令執行的步驟,我們的步驟放到一個區域裡面,程式計數器就按照第一步幹什麼,第二步幹什麼來執行。
棧:
什麼是棧呢?先看看這張圖
為了更好的進行理解,我們先來寫個遞迴:
/** * 作者:LKP * 時間:2018/11/8 */
public class Digui {
private Long i = 0l;
public void test(int a, double d) { i++; System.out.println("=====>" + i); test(a, d); }
public static void main(String[] args) { Digui app = new Digui(); app.test(0, 0.0d); } }
執行一下:
報錯了(StackOverflowError)。為什麼報錯呢?
StackOverflowError異常代表的是,當棧深度超過虛擬機器分配給執行緒的棧大小時就會出現此error。
所以棧和程式執行有關:
棧概念:先進後去的原則,剛剛出現StackOverflowError的異常,證明棧是有數量限制的。
每個棧幀裡面儲存的又是什麼呢?
區域性變數表又是什麼?
main函式一般都是主執行緒,步驟1產生的就是區域性變數表。
那為什麼又要壓棧呢?
看一下步驟2,因為當執行main執行緒的時候,add執行緒還沒有產生。當執行add的時候會把它放在main上面,為什麼這樣,這就和等下彈棧有關係了。
步驟2返回C就是最關鍵的,它就是彈棧過程,彈出的這個資料機構(add執行緒)就消失了,什麼都沒有了,包括區域性變數什麼的。
步驟3是返回到main執行緒去了。
為什麼用棧不用佇列呢?原因很簡答,因為彈棧壓棧都是最簡單的,而佇列則需要去查詢。
來看看JVM中堆、棧和方法區這三者的聯絡。
區域性變數表可以存放八大資料基本型別,再加上一種引用reference(引用就是一個地址,指向堆、常量池的地址)
回顧一開始出現的程式,結合來理解這三者的關係。
看完這篇文章,相信你對資料執行區的瞭解加深了很多。
最後再來看一下JVM記憶體區域:
1.8 永久代已經廢掉了,直接使用記憶體,不過多闡述,有興趣可自行去了解。
有什麼錯誤,或者用詞不當還希望大家留言。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69900357/viewspace-2222087/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JVM執行時資料區JVM
- JVM執行時資料區域JVM
- JVM執行時資料區概述JVM
- JVM——【執行時資料區】程式計數器JVM
- JVM——04執行時資料區(2)JVM
- JVM 執行時資料區詳解JVM
- Java-JVM-執行時資料區JavaJVM
- JVM(一)——Java 執行時的資料區域JVMJava
- JVM學習-執行時資料區域JVM
- JVM詳解(三)——執行時資料區JVM
- JVM筆記【1】-- 執行時資料區JVM筆記
- JVM執行時記憶體資料區域JVM記憶體
- JVM詳解(四)——執行時資料區-堆JVM
- JVM虛擬機器-執行時資料區概述JVM虛擬機
- 虛擬機器系列 | JVM執行時資料區虛擬機JVM
- 從零開始JVM(一):初探JVM執行時資料區域JVM
- JVM-執行時資料區之PC暫存器JVM
- JVM——記憶體區域:執行時資料區域詳解JVM記憶體
- JVM執行時資料區探索與直接記憶體的使用JVM記憶體
- 【深入學習JVM 01】執行時資料區域劃分JVM
- JVM結構-記憶體結構(執行時資料區)JVM記憶體
- 透過pl/sql計算程式的執行時間SQL
- 執行時資料區——程式計數器
- JVM執行時區域詳解。JVM
- 圖文並茂,帶你認識 JVM 執行時資料區JVM
- java的執行時資料區域Java
- 【JVM之記憶體與垃圾回收篇】執行時資料區概述及執行緒JVM記憶體執行緒
- jvm入門及理解(三)——執行時資料區(程式計數器+本地方法棧)JVM
- 透過shell指令碼來得到不穩定的執行計劃指令碼
- 03—執行時資料區概述及執行緒執行緒
- 5_執行時資料區概述
- jvm-執行時資料區(程式計數器、Java虛擬機器棧、本地方法棧)JVMJava虛擬機
- JVM程式用一個主執行緒來執行main()方法JVM執行緒AI
- java記憶體區域-執行時資料區Java記憶體
- 【JVM從小白學成大佬】2.Java虛擬機器執行時資料區JVMJava虛擬機
- Java 虛擬機器:看完就懂 JVM 架構和執行時資料區 (記憶體區域)Java虛擬機JVM架構記憶體
- Java虛擬機器-執行時資料區Java虛擬機
- Java虛擬機器 —— 執行時資料區Java虛擬機