1、什么是JVM
JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用于計算設備的規范,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實作的,
引入Java語言虛擬機后,Java語言在不同平臺上運行時不需要重新編譯,Java語言使用Java虛擬機屏蔽了與具體平臺相關的資訊,使得Java語言編譯程式只需生成在Java虛擬機上運行的目標代碼(位元組碼),就可以在多種平臺上不加修改地運行,
Java虛擬機本質上就是一個程式,當它在命令列上啟動的時候,就開始執行保存在某位元組碼檔案中的指令,
Java語言的可移植性正是建立在Java虛擬機的基礎上,任何平臺只要裝有針對于該平臺的Java虛擬機,位元組碼檔案(.class)就可以在該平臺上運行,這就是“一次編譯,多次運行”,
2、JDK、JRE和JVM關系

JDK = JRE + 開發工具(如編譯器javac.exe)
JRE = JVM + 類別庫

Java程式的開發程序為:
1、我們利用 JDK (呼叫 Java API)撰寫出 Java 源代碼,存盤于 .java 檔案中
2、JDK 中的編譯器 javac 將 Java 源代碼編譯成 Java 位元組碼,存盤于 .class 檔案中
3、JRE 加載、驗證、執行 Java 位元組碼
4、JVM 將位元組碼決議為機器碼并映射到 CPU 指令集或 OS 的系統呼叫,
3、JVM的組成結構

JVM包含兩個子系統和兩個組件
兩個子系統:
- Class loader(類裝載)
- Execution engine(執行引擎)
兩個組件:
- Runtime data area(運行時資料區)
- Native Interface(本地介面)
4、JVM運行時資料區

1、程式計數器(PC Register)
作用:記錄的是正在執行的虛擬機位元組碼指令的地址;如果正在執行的是Native方法,這個計數器值則為空,
例外:此記憶體區域是唯一一個在Java虛擬機規范中沒有規定任何OutOfMemoryError情況的區域,
2、虛擬機堆疊(JVM Stacks)
作用:是Java方法執行的記憶體模型,每個方法在執行的同時都會創建一個堆疊幀用于存盤資料,每一個方法從呼叫直至執行完成,對應堆疊幀在虛擬機堆疊中入堆疊到出堆疊的程序,
例外:會拋出StackOverflowError和OutOfMemoryErrror例外,
堆疊幀(Stack Frame)包含以下幾個部分
1、區域變數表:是存放方法引數和區域變數的區域
2、操作堆疊:是個初始狀態為空的桶式結構堆疊,在方法執行程序中,會有各種指令往堆疊中寫入和提取資訊,JVM的執行引擎式基于堆疊的執行引擎,其中的堆疊指的就是操作堆疊,i++和++i(位元組碼指令)
3、動態鏈接:每個堆疊幀中包含一個在常量池中對當前方法的參考,目的是支持方法呼叫程序的動態連接
4、方法回傳地址:方法執行有兩種退出情況,正常退出和例外退出,兩者都將回傳至方法當前被呼叫的位置,方法退出的程序相當于彈出當前堆疊幀
3、本地方法堆疊(Native Method Stacks)
作用:與虛擬機堆疊所發揮的作用非常相似,為虛擬機使用到的Native方法服務,執行緒開始呼叫本地方法時,會進入不再受JVM約束的世界,本地方法可以通過 JNI(Java Native Interface)來訪問虛擬機運行時的資料區,
例外:會拋出StackOverFlowError和OutOfMemoryError例外,
4、方法區(Method Area)
作用:用于存盤已被虛擬機加載的類資訊、常量、靜態變數、即時編譯器編譯后的代碼等資料,
例外:當方法區無法滿足記憶體分配需求時,將拋出OutOfMemoryError例外,
垃圾回收:垃圾收集行為在這個區域時比較少出現的,其記憶體回收目標主要是對常量池的回收和對型別的卸載,JDK8之前,Hotspot中方法區的實作是永久代,JDK8開始使用元空間(Meta Space),以前永久代所有內容的字串常量移至元空間,元空間直接在本地記憶體分配,
運行時常量池
1、是方法區的一部分
2、存放編譯期生成的各種字面量和符號參考
3、Class檔案中除了存有類的版本、欄位、方法、介面等描述資訊,還有一項是常量池,存有這個類的編譯期生成的各種字面量和符合參考,這部分內容將在類加載后,存放到方法區的運行時常量池中
為什么廢除1.7中永久代?
1、移除永久代是為融合Hotspot JVM與JR'ockit VM而做出的努力,因為JRockit沒有永久代,不需要配置永久代
2、現實使用中,由于永久代記憶體經常不夠用或發生記憶體泄露,爆出例外 java.lang.OutOfMemoryError: PermGen
3、基于此,將永久區廢棄,而改用元空間,改為了使用本地記憶體空間
5、堆(Heap)
作用:Java虛擬機所管理的記憶體中最大的一塊,Java堆是被執行緒共享的一塊記憶體區域,在虛擬機啟動時創建,此記憶體區域的唯一目的就是存放物件實體,幾乎所有的物件實體都在這里分配記憶體,
例外:如果在堆中沒有記憶體完成實體分配,并且堆也無法再擴展時,將會拋出OutOfMemoryError例外,
6、直接記憶體(Direct Memory)
直接記憶體(Direct Memory)并不是虛擬機運行時資料區的一部分,也不是 Java 虛擬機規范中定義的記憶體區域,
在 JDK 1.4 中新加入了 NIO,引入了一種基于通道(Channel)與緩沖區(Buffer)的 I/O 方式,它可以使用 Native 函式庫直接分配堆外記憶體,然后通過一個存盤在 Java 堆中的 DirectByteBuffer 物件作為這塊記憶體的參考進行操作,這樣能在一些場景中顯著提高性能,因為避免了在 Java 堆和 Native 堆中來回復制資料,
程式計數器、虛擬機堆疊、本地方法堆疊是執行緒私有的,方法區、堆是執行緒共享的
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286385.html
標籤:其他
