這篇文章將為大家詳細(xì)講解有關(guān)Java程序的運(yùn)行原理是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
創(chuàng)新互聯(lián)主要從事成都做網(wǎng)站、成都網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)渝中,十年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18982081108
class文件包含Java程序執(zhí)行的字節(jié)碼
數(shù)據(jù)嚴(yán)格按照格式緊湊排列在class文件的二進(jìn)制流,中間無分割符
文件開頭有一個(gè)0xcafebabe(16進(jìn)制)特殊的標(biāo)志
線程獨(dú)占: 每個(gè)線程都會(huì)有它獨(dú)立的空間,隨線程的生命周期而創(chuàng)建和銷毀
線程共享: 所有線程都能訪問這塊內(nèi)存數(shù)據(jù),隨虛擬機(jī)或GC而創(chuàng)建和銷毀
方法區(qū)是各個(gè)線程共享的內(nèi)存區(qū)域
用于存儲(chǔ)已被虛擬機(jī)加載的類信息, 常量,靜態(tài)變量, 即時(shí)編譯后的代碼等數(shù)據(jù)
雖然Java虛擬機(jī)規(guī)范把方法區(qū)描述為堆的一個(gè)邏輯部分, 但它卻有一個(gè)別名叫Non-Heap, 目的應(yīng)該是與Java堆區(qū)分開來
Oracle的Hotspot虛擬機(jī)在Java7中方法區(qū)放在’永久代’(Permanent Generation), Java8放在元數(shù)據(jù)空間, 并且通過GC機(jī)制對(duì)這個(gè)區(qū)域進(jìn)行管理
運(yùn)行時(shí)常量池是方法區(qū)的一部分
Java堆是被所有共享的一塊內(nèi)存區(qū)域, 在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建
存放對(duì)象的實(shí)例
垃圾收集器的主要管理區(qū)域
Java堆還可以細(xì)分為: 新生代和老年代, 新生代又可以細(xì)分為Eden 空間, From Survivor空間 和To Survivor空間
空間滿了會(huì)拋OutOfMemoryError
Java虛擬機(jī)棧是線程私有的, 它的生命周期與線程相同
Java虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型: 每個(gè)方法被執(zhí)行的的時(shí)候都會(huì)同時(shí)創(chuàng)建一個(gè)棧幀(棧幀是方法運(yùn)行時(shí)的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu))用于存儲(chǔ)局部變量表, 操作棧, 動(dòng)態(tài)鏈接, 方法出口等信息.
棧內(nèi)存默認(rèn)最大是1M, 超出則拋出StackOverFlowError
本地方法棧與虛擬機(jī)棧的功能類似, 虛擬機(jī)棧是為虛擬機(jī)執(zhí)行Java方法而準(zhǔn)備的, 本地方法棧是為虛擬機(jī)使用Native本地方法而準(zhǔn)備的
Hotspot虛擬機(jī)中虛擬機(jī)棧與本地方法棧的實(shí)現(xiàn)方式一樣, 超出大小后也會(huì)拋StackOverFlowError
程序計(jì)數(shù)器是線程私有的一塊較小的內(nèi)存空間
記錄當(dāng)前線程執(zhí)行的字節(jié)碼位置, 存儲(chǔ)的是字節(jié)碼指令地址, 如果執(zhí)行Native方法, 則計(jì)數(shù)器為空
CPU同一時(shí)間, 只會(huì)執(zhí)行一條線程的指令. JVM多線程會(huì)輪流切換并分配CPU的執(zhí)行時(shí)間的方式. 為了線程切換后, 需要通過程序計(jì)數(shù)器來恢復(fù)正確的執(zhí)行位置
使用Demo.Java進(jìn)行測(cè)試, 運(yùn)行javac Demo.java
編譯成class文件, 然后運(yùn)行javap -v Demo.class > Demo.txt
查看class文件內(nèi)容
Demo.Java
public class Demo{
public static void main(String[] args){
int x = 500;
int y = 100;
int a = x / y;
int b = 50;
System.out.println(a + b);
}
}
Demo.txt
Classfile /E:/*/Demo.class
Last modified 2019-6-30; size 412 bytes
MD5 checksum efd785af33e58aa9fc9834110b74b87b
Compiled from "Demo.java"
public class Demo
minor version: 0 //次版本號(hào) major version: 52 //主版本號(hào) 版本號(hào)規(guī)則: JDK5,6,7,8分別對(duì)應(yīng)49,50,51,52
flags: ACC_PUBLIC, ACC_SUPER //訪問標(biāo)志Constant pool: // 常量池 類信息包含的靜態(tài)常量, 編譯之后就能確認(rèn) #1 = Methodref #5.#14 // java/lang/Object."":()V
#2 = Fieldref #15.#16 // java/lang/System.out:Ljava/io/PrintStream;
#3 = Methodref #17.#18 // java/io/PrintStream.println:(I)V
#4 = Class #19 // Demo
#5 = Class #20 // java/lang/Object
#6 = Utf8
#7 = Utf8 ()V
#8 = Utf8 Code
#9 = Utf8 LineNumberTable
#10 = Utf8 main
#11 = Utf8 ([Ljava/lang/String;)V
#12 = Utf8 SourceFile
#13 = Utf8 Demo.java
#14 = NameAndType #6:#7 // "":()V
#15 = Class #21 // java/lang/System
#16 = NameAndType #22:#23 // out:Ljava/io/PrintStream;
#17 = Class #24 // java/io/PrintStream
#18 = NameAndType #25:#26 // println:(I)V
#19 = Utf8 Demo
#20 = Utf8 java/lang/Object
#21 = Utf8 java/lang/System
#22 = Utf8 out
#23 = Utf8 Ljava/io/PrintStream;
#24 = Utf8 java/io/PrintStream
#25 = Utf8 println
#26 = Utf8 (I)V
{
public Demo(); // 默認(rèn)隱式無參的構(gòu)造函數(shù) descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: return
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]); //程序的入口main方法 descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC //訪問控制 Code:
stack=3, locals=5, args_size=1 //方法棧棧幀中操作數(shù)棧的深度,本地變量數(shù)量,參數(shù)數(shù)量 0: sipush 500 //Jvm執(zhí)行引擎執(zhí)行這些源碼編譯過后的指令碼, javap翻譯出來的 3: istore_1 //是操作符, class 文件內(nèi)存儲(chǔ)的是指令碼, 前面的數(shù)據(jù)是偏移量,
4: bipush 100 //Jvm根據(jù)這個(gè)去區(qū)分不同的指令. 詳情參照'JVM指令碼表'
6: istore_2
7: iload_1
8: iload_2
9: idiv
10: istore_3
11: bipush 50
13: istore 4
15: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
18: iload_3
19: iload 4
21: iadd
22: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
25: return
LineNumberTable:
line 3: 0
line 4: 4
line 5: 7
line 6: 11
line 7: 15
line 8: 25
}
SourceFile: "Demo.java"
關(guān)于Java程序的運(yùn)行原理是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。