經同事推薦,這兩天在看深刻理解Java虛擬機.我把一些內容整理出來,加上我本身的理解記錄下來.java
你們都知道C,C++都要手動申請和釋放內存,下降了開發效率,並且容易出錯,一旦出錯了,都是比較大的問題.而Java這種基於虛擬機的語言申請內存以及.垃圾內存回收都幫我作好了,要了解JVM內存以及垃圾回收機制才能對整個JVM體系以及本身所寫的代碼有更好的認識.數組
一.JVM內存區域
線程
JVM內存區域主要分爲: Java堆,虛擬機棧,本地方法棧,程序計數器,方法區.下面來點一下各個區域的做用.指針
java堆:存放對象實例的區域.在JVM啓動的時候建立,是垃圾回收器主要的管理區域.可進行擴展的,經過-Xmx設置堆最大內存.和-Xms堆最小內存來設置,當擴展時,內存不夠,則會拋出OutOfMemeryError.對象
虛擬機棧:線程私有的區域,當進入一個方法時會建立棧幀,用來存放局部變量(基本類型,引用),操做數棧,方法出口等信息,當線程請求棧深度超出虛擬機容許的深度時,會拋出StackOverfloweError.當動態擴展,內存不夠時,會拋出OutOfMemeryError.內存
本地方法棧,和虛擬機棧同樣的功能,用於native方法.開發
程序計數器:線程私有的區域,指向正在執行的字節碼指令.若是是native方法,則爲空.虛擬機
方法區:存放各線程共享的數據,虛擬機加載的類的信息,靜態變量,常量等.方法區裏面有一個常量池,常量池也會在運行時動態添加,如String.intern()方法.效率
二.對象的內存分佈變量
對象在內存中分爲三個部分:對象頭,實例數據,對齊填充
1.對象頭:存儲對象運行時的數據,HashCode,GC分代年齡,鎖狀態標誌,線程持有的鎖,數組長度.32位虛擬機中對象頭是32位,而64位虛擬機中對象頭是64位
2.實例數據:定義的各類類型的字段.
3.對齊填充:在不知足8字節的狀況下填充0補齊.
三.對象的訪問定位
兩種方式,一種是句柄,第二種是直接指針
1.句柄:堆內存中有個句柄池,存放了對象在堆中的實例地址和方法區中對象類信息.經過引用找到對象的句柄,而後經過句柄找到對象的實例以及類信息.
2.直接指針:引用直接定位到堆中實例,可是實例要有信息去指向方法區中存放的類信息.速度快.可是當GC移動了對象地址須要修改引用的值.HotSpot虛擬機用的是第二種方式.