1. 程式人生 > >讀書筆記之深入理解Java虛擬機器

讀書筆記之深入理解Java虛擬機器

深入理解Java虛擬機器


2.2 執行時資料區域 2.2.1.程式計數器 可以看做是當前執行緒所執行的位元組碼的 行號指示器。 每個執行緒都需要一個 獨立的程式計數器。(這類記憶體區域為"執行緒私有"的記憶體) 如果執行緒正在執行一個java方法,計數器記錄的是正在執行的虛擬機器 位元組碼指令的地址;如果正在執行的是native方法,計數器值為 空(undefined)。 此記憶體區域是 唯一一個在java虛擬機器規範中 沒有規定任何OutOfMemoryError情況
的區域。
2.2.2.Java虛擬機器棧 是執行緒私有。生命週期和執行緒相同。 描述的是java方法執行的記憶體模型:每個方法在執行的同時會建立一個棧幀用於儲存區域性變量表、運算元棧、動態連結、方法出口等資訊。每個方法從呼叫直至執行完成的過程,就對應著一個棧幀在虛擬機器棧中入棧到出棧的過程。 對這個區域規定了兩種異常狀況:如果 執行緒請求的棧深度大於虛擬機器所允許的深度,將丟擲StackOverflowError異常;如果虛擬機器棧可以動態擴充套件(當前大部分java虛擬機器都可以動態擴充套件,只不過java虛擬機器規範中也規定允許固定長度的虛擬機器棧),如果 擴充套件時無法申請足夠的記憶體,就會丟擲OutOfMemoryError
異常。
2.2.3.本地方法棧 區別:虛擬機器棧為虛擬機器執行java方法(位元組碼)服務;而本地方法棧為虛擬機器使用到的native方法服務。
2.2.4.java堆 是java管理記憶體中最大的一塊;目的是存放物件例項;java虛擬機器規範中描述:所有的物件例項以及陣列都要在堆上分配,但是隨著JIT編譯器的發展和逃逸分析技術逐步成熟,棧上分、標量替換優化技術會導致一些變化。 java虛擬機器規範規定,java堆可以處於物理上不連續的記憶體空間,只要邏輯上是連續的。在實現上,既可以實現成固定大小的,也可以是可擴充套件的,不過當前主流虛擬機器都是按照可擴充套件實現的(通過-Xmx和-Xms控制)。如果在堆中沒有記憶體完成例項分配,並且堆無法擴充套件時,丟擲 OutOfMemoryError
異常。
2.2.5.方法區 用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。 java虛擬機器規範規定其不需要連續的記憶體和可以選擇固定大小或可擴充套件,還可以選擇不實現垃圾收集。 規定當方法區無法滿足記憶體分配需求時,丟擲 OutOfMemoryError異常。
2.2.6.執行時常量池 是方法區的一部分,用於存放編譯器生成的各種字面量和符號引用。 具有動態性,執行期間也可能將新常量放入池中 當常量池無法申請到記憶體時,丟擲 OutOfMemoryError異常。
2.2.7.直接記憶體 並不是虛擬機器執行時資料區的一部分,也不是java虛擬機器規範中定義的記憶體區域。但這部分頻繁使用,也可能導致 OutOfMemoryError。 在jdk1.4中新加入的NIO引入了基於通道與緩衝區的I/O方式,可以使用Native函式庫直接分配堆外記憶體,然後通過一個儲存在java堆中的DirectByteBuffer物件作為這塊記憶體的引用進行操作。提高效能。 伺服器管理員在平【日誌虛擬機器引數是,設定Xmx等引數,如果忽略直接記憶體,會導致個記憶體總和大於實體記憶體,導致動態擴充套件時 OutOfMemoryError。
2.3.HotSpot虛擬機器物件探祕
(還在精讀中,後續更新) TODO