java 句柄 内存_Java内存区域学习
運行時區域
Java虛擬機在執行Java程序過程中把其所管理的內存劃分成若干個不同的數據區域。
程序計數器
當前線程所執行的字節碼的指示器。通過改變這個計數器的值來選取下一個需要執行的字節碼指令,分支、循環、跳轉、異常、線程恢復等都需要這個計數器完成。
每個線程一個獨立的程序計數器,各線程之間互不影響,獨立存儲。
執行Java方法時:正在執行虛擬字節碼的指令地址
執行Native方法:值為空(Undefined)
復制代碼
唯一一個Java虛擬機規范中沒有規定OutOfMemoryError的區域
虛擬機棧
線程私有,生命周期和線程一致。
描述的是Java方法執行的內存模型:方法執行同時創建一個棧幀,方法從調用到執行完成,就是一個棧幀在虛擬機棧中入棧到出棧的過程。
其中棧幀用于存儲:局部變量表、操作數棧、動態鏈接、方法出口等信息。
局部變量表中存放了編譯期間可知的基本數據類型和對象引用。
64位的long和double類型的數據會占2個局部空間變量,其余類型只占1個。因局部變量表中所需內存是在編譯期間完成的,所以這個方法在幀中需要分配多少局部變量空間是確定的。
這部分區域異常:StackOverFlowError和OutOfMemoryError
、
本地方法棧
與虛擬機棧的作用類似。本地方法棧是為Native方法服務。拋出異常與虛擬機棧一致。
堆
堆是Java虛擬機中內存最大的一塊。線程共享,虛擬機啟動時創建。存放對象實例。
幾乎所有的對象都在這里分配內存。【隨著JIT編譯器的發展和逃逸分析技術的成熟,棧上分配和標量替換,對象不一定在堆中分配】
堆是垃圾收集管理器的主要區域,也叫GC堆。細分為:新生代、老年代。eden->from survivor->to survivor
通過-Xmx和-Xms控制擴展,無法擴展時拋出OutOfMemoryError異常
方法區
線程共享。存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯的代碼。也叫非堆,也稱永久代。
-XX:MaxPermSize
內存回收目標:常量池的回收和類的卸載
OutOfMemoryError
運行時常量池
方法區的一部分
OutOfMemoryError
直接內存
不是虛擬機運行時區的一部分。
JDK1.4新加入的NIO類,引入Channel和Buffer的I/O方式,使用Native函數庫直接分配堆外內存,使用DirectByteBuffer作為這塊內存的引用進行操作。
受本機內存大小和處理器尋址空間的限制
OutOfMemoryError
虛擬機中的對象
對象的創建
當遇到new指令時
首先檢查這個指令的參數是否能在常量池中定位到一個類的符號引用。【并檢查該符號引用代表的類是否已被加載、解析、初始化過,若沒有則執行類加載】
類加載通過之后,為新生對象分配內存
內存分配完成后,需將分配到的內存空間都初始化為零值,不包括對象頭
接下來,虛擬機要對對象進行必要的設置,設置對象頭。如這個對象是那個類的實例。如何才能找到類的元數據信息、對象的哈希碼、對象的GC分代年齡等信息。
復制代碼
分配內存方式:
指針碰撞
空閑列表
復制代碼
當使用Serial、ParNew等帶compact過程的收集器時:分配算法是指針碰撞
使用CMS基于Mark-Sweep算法的收集器時:分配算法采用空閑列表
分配對象內存空間并發下線程安全問題:
采用CAS加上失敗重試保證更新的原子性
把內存分配動作按線程劃分在不同的空間進行,即每個線程在Java堆中預先分配一塊小內存,成為本地線程分配緩沖區【TLAB】 -XX:+、-UseTLAB
復制代碼
對象創建完成之后還有進行init,按照程序員的意愿進行初始化。
對象內存布局
對象內存布局分為三塊
對象頭、實例數據、對齊填充
復制代碼
對象頭
對象頭包含兩部分:
存儲對象自身的運行數據
類型指針
復制代碼
對象自身的運行數據
包含哈希碼、GC分代年齡、鎖狀態標志、線程持有鎖、偏向線程ID、偏向時間戳等。也稱Mrak Word
類型指針
對象指向它的類元數據的指針。虛擬機通過這個指針來確定對象是屬于哪個類的實例
對象實例數據部分
對象真正存儲的有效信息,各種類型的字段內容。
對齊填充部分
不是必然存在的。起著占位符的作用。
對象起始地址必須是8字節的整數倍。當對象實例數據部分沒有對齊時,就需要對齊填充了。
對象的訪問定位
對象的訪問定位目前有兩種流行的方式:
使用句柄
直接指針
復制代碼
句柄
直接指針
對比
使用句柄好處:棧中引用存儲的是穩定的句柄地址,對象被移動時只會改變句柄中的實例數據指針,引用本身不需變化
使用直接引用好處:速度快,節省一次指針定位的時間開銷
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的java 句柄 内存_Java内存区域学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java List最大_在java中获取
- 下一篇: java ftp 下载慢_Java实现f