JVM(周志明著深入了解JVM书归纳,新写一点就重新传一遍)
JVM
第2章 Java內存區域與內存溢出異常
運行時數據區:方法區、虛擬機棧、本地方法棧、堆、程序計數器。
執行引擎
本地庫接口
本地方法庫
I.概念
1.程序計數器(線程私有)
作用:當前線程所執行的字節碼的信號指示器。
由于Java虛擬機的多線程功能是通過線程輪流切換并分配處理器執行時間的方式來實現的,在任何一個確定的時刻,一個處理器只會執行一條線程中的指令。因此,為了線程切換后能恢復到正確的執行位置,每條線程都需要有一個獨立的程序計數器,各條線程之間的計數器互不影響,獨立存儲,我們稱這類內存區域為“線程私有”的內存。
如果線程正在執行一個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;如果正在執行的是Native方法,這個計數器則為空(Undefined),此內存區域是唯一一個在Java虛擬機規范中沒有規定任何OOM情況的區域。
2.Java虛擬機棧(線程私有)
生命周期與線程相同。
虛擬機棧描述的是Java方法執行的內存模型:每個方法被執行的時候都會同時創建一個棧幀用于存儲局部變量表、操作棧、動態鏈接、方法出口等信息。每一個方法被調用直至執行完成的過程,就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程。
局部變量表所需的內存空間在編譯期間是完全確定的,在方法運行期間不會改變局部變量表的大小。局部變量表中存放了各種基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用(reference類型,不等同于對象本身)和returnAddress類型。其中64位長度的long和double類型的數據會占用2個局部變量空間(Slot),其它只占用1個。
3.本地方法棧
與虛擬機棧發揮作用相似。區別:虛擬機棧為java方法(字節碼)服務;本地方法棧為虛擬機使用到的Native方法服務。(有些虛擬機將本地方法棧與虛擬機棧合二為一,本地方法區域也會拋出StackOVerflowError和OOM異常)
4.Java堆
對大多數應用來說,Java堆是虛擬機所管理的內存中最大的一塊。Java堆是被所有線程共享的一塊內存區域,在虛擬機啟動時創建。
Java堆可以分為:Eden空間、From Survivor空間、To Survivor空間等。(Eden、S1、S2)
如果堆中沒有內存完成實例分配,并且堆也無法再擴展時,將會拋出OOM異常。
5.方法區(別名:非堆)
與Java堆一樣,是各個線程共享的內存區域。
用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器變異后的代碼等數據。
當方法區無法滿足內存分配需求時,將拋出OOM異常。
6.運行時常量池
是方法區的一部分。
Class文件中除了有類的版本、字段、方法、接口等描述的信息外,還有一項信息是常量池,用于存放編譯器生成的各種字面量和符號引用,這部分內容將在類加載后存放到方法區的運行時常量池中。
運行時也能將新的常量放入常量池中,開發人員用得比較多的是String類的intern()方法。
當常量池無法再申請到內存時會拋出OOM異常。
7.直接內存
不是虛擬機運行時數據區的一部分,也不是Java虛擬機規范中定義的內存區域,但也頻繁地使用,并且也可能導致OOM異常。
JDK4加入了NIO類,引入了異種基于通道(channel)與緩沖區(Buffer)的I/O方式,它可以使用Native函數庫直接分配堆外內存,然后通過一個存儲在Java堆里面的DirectByteBuffer對象作為這塊內存的引用進行操作。這樣能在一些場景中顯著提高性能,因為避免了在Java堆和Native堆中來回復制數據。
本機直接內存的分配不會受到Java堆大小的限制,但是會受到本機總內存(包括RAM及SWAP區或者分頁文件)的大小及處理器尋址空間的限制。分配內存時經常會忽略直接村內,使得各個區域的綜合大于物理內存限制(包括物理上的和操作系統的限制),從而導致動態擴展時出現OOM異常。
II.對象訪問
這塊自己平時就有琢磨過,在沒看任何資料的情況下,只是自己假象了2種情況,來看看真正的對象訪問機制。
對象訪問在Java中無處不在,但即使是最簡單的訪問,也會涉及到Java棧、Java堆、方法區三個最重要的內存區域之間的關聯關系。
使用句柄方式訪問:Java堆中將會劃分出一塊內存來作為句柄池,reference中存儲的就是對象的句柄地址,而句柄中包含了對象實例數據和類型數據各自的具體地址信息。最大好處:reference中存儲的是穩定的句柄地址,在對象被移動(垃圾回收時移動對象是非常普遍的行為)時只會改變句柄中的實例數據指針,而reference本身不需要被修改。句柄池中有兩個指針:實例數據的和類型數據的,會分別去到實例池和方法區中的對象類型數據中。
使用直接指針訪問:對象實例數據和到對象類型數據的指針是放在一起的,所以節省了一次指針定位的時間開銷,由于對象的訪問在Java中非常頻繁,因此這類開銷積少成多后也是一項非擦汗那個可觀的執行成本。
總結
以上是生活随笔為你收集整理的JVM(周志明著深入了解JVM书归纳,新写一点就重新传一遍)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 周志明虚拟机最新版,大厂面试必备宝典
- 下一篇: 《深入理解JAVA虚拟机》周志明 第三版
