深入JAVA虛擬機器-第二版
第一章 JAVA體系結構介紹
- java應用程式可以使用兩種類裝載器,啟動(bootstrap)類裝載器和使用者自定義裝載器。
每一個類被裝載的時候,java虛擬機器都監視著這個類,看它是被什麼裝載器裝載的,當被裝載的類引用了其他類的時候,
會使用相同的類裝載器去裝載被引用的類。因此預設情況下只能看到被同一個類裝載器裝載的類,通過這種方法,java允許
在java程式中簡歷多個名稱空間,每一個類載入器都有自己的名稱空間。 -
class
檔案,執行在JVM上的二進位制檔案
第三章 安全(--看完再回顧本章)
- JAVA沙箱中類裝載體系結構是第一道防線
- 防止惡意程式碼干涉善意程式碼
- 守護被信任類庫的邊界
- 將程式碼分類,確定該類程式碼可以執行些些操作
- class 檔案檢測器
- 檢驗位元組碼的的完整性
- 型別資料語義檢查
- 位元組碼驗證
- 符號引用驗證
- 二進位制相容
- JVM內建安全特性
- 型別安全的引用轉換
- 結構化的記憶體訪問
- 自動垃圾收集
- 陣列邊界檢查
- 空引用檢查
- 禁止對記憶體進行非結構化訪問
- 異常的結構化處理
- 安全管理器和java api
- 程式碼簽名和認證,將一個未簽名的class檔案通過雜湊和私鑰得到一個帶有簽名後雜湊的檔案
- 訪問控制器
第五章 java虛擬機器
- 生命週期,main作為函式的起點,每一個程式都執行一個虛擬機器例項上。java虛擬機器上兩種執行緒,一種是守護執行緒,另一種是非守護執行緒
守護執行緒是由jvm自己使用的,比如垃圾回收的執行緒,而開始於main函式的執行緒是非守護執行緒。只要還有非守護執行緒在執行,虛擬機器還是存活的
,所有非守護執行緒退出時,虛擬機器會自動退出。
java 虛擬機器的結構體系
-------------------
| 類裝載器子系統 |
-------------------
|
------------------------------------------------------------------
| | | | | | |
| 方法區 堆 java棧 PC暫存器 本地方法棧 |
------------------------------------------------------------------
| |
執行引擎 ————————————————> 本地方法介面
- 一些點
- 方法區和堆記憶體是由所有的執行緒共享的,虛擬機器裝載class檔案時,會把類的資料放在方法區中,當程式執行時,會把根據類資料建立的物件
放在堆記憶體中。 - 當新執行緒被建立時,都將得到一個
PC暫存器
和一個JAVA棧
,PC暫存器
總是指向下一條被執行的指令,java棧則儲存方法的呼叫狀態。(區域性變數
,引數
,返回值
,運算中間值
) - java 棧是有很多的棧幀組成,當執行緒呼叫一個方法的時候,,JVM將新的棧幀入棧,當函式返回時,棧幀被出棧。
- 資料型別
- 基本型別(float, double, byte, short, int, long, char, boolean, returnAddress)
64 32 8 16 32 64 16 - 引用型別(類,介面 ,陣列)
方法區
- 方法區的資料共享,因此是必須執行緒安全的。虛擬機器允許程式設計師指定方法區的大小
- 方法區會在記憶體中儲存類的以下資訊:
型別的全限定名(包名+.+類名)
此類超類的全限定名
類還是介面
修飾符(public ,abstruct, final)
介面全限定名的有序列表
型別的常量池
欄位資訊(欄位名,型別,修飾符)
方法資訊(方法名,型別,修飾符)
一個到類ClassLoder的引用
一個到Class類的引用(forName(),讓使用者得到已裝載物件的Class例項)
方法位元組碼
運算元棧和該方法在棧幀中區域性變數的大小
異常表
下面看一看流程
class Volcano(){
public static void main(String args[]){
Lava lava = new Lava();
lava.flow();
}
}
- 例如我們要執行一個叫
Volcano
的類,當我們告訴JVMVolcano
這個名字
- JVM會找到並讀入
Volcano.class
檔案 - 然後匯入其中的二進位制流,並把相應的資料存在方法區
- 通過執行方法區中的位元組碼,開始執行main()方法,在執行時會一直持有指向常量池的指標
- main方法中第一條指令是給常量池第一個類分配象的記憶體,於是在常量池中找到第一項,發現是對另一個類Lava的引用
- 檢查方法區,看是否被裝載,發現沒有被裝載,於是查詢
Lava.class
檔案裝載,同樣把資訊儲存在方法區中 - 接著指向常量池第一行的指標替換掉常量池的第一項(
Lava
的全限定名)->常量池的解析
(符號引用替換成直接引用,本地指標) - 虛擬機器準備為Lava分配記憶體,並用這個指標訪問它的類資訊,找出類資訊中的需要為這個類分配多少堆記憶體
- 虛擬機器確定了大小,就在堆上為物件分配記憶體,並初始化常量值。然後把物件的引用入棧,第一條指令執行完成。
- 接下來通過這個引用呼叫flow方法
堆
java一個虛擬例項中只有一個堆空間,所有執行緒共享
java 只有在堆中分配記憶體的指令,沒有釋放的指令,垃圾收集器會負責堆和方法區的記憶體回收
堆和方法區一樣也不是一個連續的記憶體區,是可擴充套件的
堆上的物件還有一部分資料,是物件鎖(互斥鎖),請求可以追加,請求幾次,必須釋放幾次,例如請求了4次,只釋放了3次,那還是持有這個物件鎖。
堆上物件還有一部分資料與垃圾收集器有關,垃圾回收器必須跟蹤每個物件。
陣列是一個物件,總是儲存在堆中
PC(程式計數器)暫存器,在每個執行緒中有一個,它有一個字的大小,儲存一個本地指標,總是指向下一條將要執行的指令。
java 棧
- 每當啟用一個執行緒,JVM會為它分配一個java 棧。
- 棧幀的組成
- 區域性變數區 -> 一個陣列,以字(32bit)為單位,型別int,float,returnAddress的值再陣列中佔一項,byte,short,char會被轉化成int,也佔一項,double,long佔2項。任何一個例項方法(非static),的陣列第一項都是物件本身的reference.
- 運算元棧 -> byte,short,char會被轉化成int,和上面一樣,只有在存回堆中是會被轉化為原來型別。他也是一個陣列,但是按照棧操作來訪問。由於java虛擬機器沒有暫存器,java的指令是通過運算元棧中取得運算元的。
- 棧幀資料,支援常量池的解析正常方法返回和異常派發機制的資料。
為了處理執行期的異常退出情況,幀資料區儲存一個對此方法的異常表的引用。當方法丟擲異常,會在異常表中查詢對應的異常,如果找到了匹配的catch語句,就會交給ccatch中的程式碼處理,如果沒有則異常中止。 -
兩站不同的虛擬機器實現的幀分配
- 本地方法棧,取決於設計者的實現
執行引擎(沒看太明白)
- 執行中java程式的每一個執行緒都是一個獨立的虛擬機器執行引擎的例項。
- 從執行緒的生命週期開始,它要麼在執行位元組碼,要麼在執行native方法。
- 指令集,指令集關注的中心是運算元棧。運算元棧中的數值必須按照適合他們型別的方式使用。比如壓入棧4個
int
,卻把他們當做兩個long
來做操作,是非法的 。
第六章 JAVA class檔案 (粗略看)
java class檔案是對java程式二進位制檔案的精確定義。一個class檔案中指包括一個class 或者interface.
class檔案不一定與java語言有關,別的語言也可以編譯成class檔案在虛擬機器上執行。
- class 檔案組成
- magic ,每個class檔案的前四個位元組 0xCAFEBABE,用來分辨是否是class檔案。
- minor_version major_version b版本號。
- constant_pool_count 常量池的數量,constant_pool 常量池
- access_flags 類的修飾資訊,public ,private ,static 等
- this_class 指向常量池的索引
- super_class 超類常量池索引
第七章 型別的生命週期
- 類主動裝載的時機
- 建立例項時(new, 反射,克隆,反序列化)
- 呼叫類中的靜態方法
- 使用類或介面的靜態欄位或者對欄位賦值(final 修飾的靜態變數除外,它被初始化為一個編譯時的常量表示式)
- 呼叫api反射方法
- 初始化子類
- 含有main函式的類
- 所有類的初始化都要求它的超類在此之前初始化了。(介面不是)
- 裝載
- 通過完全限定名產生一個二進位制流
- 解析二進位制檔案
- 建立一個該型別Class例項
- 初始化
- 所有類變數初始化語句和型別的靜態初始化器都被java編譯器收集到一起放在一個特殊的方法<clinit>中,並非所有的類都有這個方法。
- 如果多個執行緒需要初始化一個類,僅僅允許一個執行緒來執行初始化,其他執行緒需要等待。完成後需要通知其他等待執行緒。
物件生命週期
- 例項化
new
reflect.newInstance()
clone()
ObjectInputStream.getObject
堆中分配記憶體,然後賦予例項變數初始值
型別當沒有引用的時候會被解除安裝,同樣通過垃圾回收器。
第八章 連結模型
相關文章
- [深入理解Java虛擬機器]第二章 HotSpot虛擬機器物件探祕Java虛擬機HotSpot物件
- 深入理解java虛擬機器Java虛擬機
- 深入理解Java虛擬機器(一)Java虛擬機
- 深入理解Java虛擬機器(二)Java虛擬機
- 《深入理解Java虛擬機器(第2版)》分享下載Java虛擬機
- 《深入理解java虛擬機器》第3版筆記3Java虛擬機筆記
- 深入理解Java虛擬機器 --- 垃圾回收器Java虛擬機
- 深入學習Java虛擬機器——虛擬機器位元組碼執行引擎Java虛擬機
- 【深入理解Java虛擬機器】垃圾回收Java虛擬機
- 《深入理解java虛擬機器》學習筆記4——Java虛擬機器垃圾收集器Java虛擬機筆記
- 《深入理解Java虛擬機器》個人讀書總結——JAVA虛擬機器記憶體Java虛擬機記憶體
- [深入理解Java虛擬機器]第二章 記憶體區域Java虛擬機記憶體
- [深入理解Java虛擬機器]第二章 實戰 :OutOfMemoryError異常Java虛擬機Error
- 深入理解Java虛擬機器8 虛擬機器位元組碼執行引擎Java虛擬機
- Dalvik虛擬機器、Java虛擬機器與ART虛擬機器虛擬機Java
- (深入理解 Java虛擬機器)一篇文章帶你深入瞭解Java 虛擬機器類載入器Java虛擬機
- 《深入理解java虛擬機器》學習筆記7——Java虛擬機器類生命週期Java虛擬機筆記
- 《深入理解 Java 虛擬機器》筆記整理Java虛擬機筆記
- 深入Java虛擬機器之 -- 總結面試篇Java虛擬機面試
- [深入理解Java虛擬機器]執行緒Java虛擬機執行緒
- 《深入理解Java虛擬機器》個人筆記Java虛擬機筆記
- java虛擬機器和Dalvik虛擬機器Java虛擬機
- Android 虛擬機器 Vs Java 虛擬機器Android虛擬機Java
- 深入理解Java虛擬機器(類載入機制)Java虛擬機
- 深入理解Java虛擬機器 - 類載入機制Java虛擬機
- 深入理解Java虛擬機器 --- 類載入機制Java虛擬機
- 深入理解java虛擬機器之垃圾收集器Java虛擬機
- 深入理解虛擬機器之虛擬機器類載入機制虛擬機
- 深入理解Java虛擬機器之實戰OutOfMemoryErrorJava虛擬機Error
- 深入理解Java虛擬機器之垃圾回收篇Java虛擬機
- 《深入理解Java虛擬機器》讀書筆記Java虛擬機筆記
- 深入淺出Lua虛擬機器虛擬機
- Java虛擬機器(JVM)Java虛擬機JVM
- Java虛擬機器(轉)Java虛擬機
- 深入理解java虛擬機器——讀書筆記1Java虛擬機筆記
- 深入理解Java虛擬機器(類檔案結構)Java虛擬機
- 深入理解Java虛擬機器之自己編譯JDKJava虛擬機編譯JDK
- 深入理解Java虛擬機器 – 類檔案結構Java虛擬機