java虚拟机 第二章Java内存区域与内存溢出异常
1、運(yùn)行時(shí)數(shù)據(jù)區(qū)域
1.1、程序計(jì)數(shù)器
線程私有,當(dāng)前線程所執(zhí)行的字節(jié)碼行號(hào)指示器,
Java虛擬機(jī)的多線程是通過(guò)線程輪流切換處理器執(zhí)行時(shí)間的方式來(lái)分配
1.2、Java虛擬機(jī)棧
線程私有,,虛擬機(jī)的局部變量表每個(gè)方法在執(zhí)行的時(shí)候都會(huì)創(chuàng)建棧幀用于存儲(chǔ)局部變量,操作數(shù)棧,動(dòng)態(tài)鏈接方法出口等信息,每個(gè)方法從開(kāi)始到結(jié)束
對(duì)應(yīng)著一個(gè)棧幀從入棧到出棧的過(guò)程,
1.3、本地方法棧
線程私有,本地方法棧是為虛擬機(jī)執(zhí)行native方法服務(wù),有的虛擬機(jī)獎(jiǎng)本地方法棧與虛擬機(jī)棧合二為一。
1.4、Java堆
GC堆,垃圾收集器管理的主要區(qū)域,用于存放對(duì)象實(shí)例,幾乎所有的Java對(duì)象實(shí)例都在這里分配空間,
1.5、方法區(qū)
用于存放虛擬機(jī)加載的類信息,常量,靜態(tài)變量,方法區(qū)中包含的都是在整個(gè)程序中永遠(yuǎn)唯一的元素,如class,static變量
1.6、運(yùn)行時(shí)常量池
JVM在執(zhí)行某個(gè)類的時(shí)候,必須經(jīng)過(guò)加載、連接、初始化,而連接又包括驗(yàn)證、準(zhǔn)備、解析三個(gè)階段。
而當(dāng)類加載到內(nèi)存中后,jvm就會(huì)將class常量池中的內(nèi)容存放到運(yùn)行時(shí)常量池中,由此可知,運(yùn)行時(shí)常量池也是每個(gè)類都有一個(gè)。
在解析階段,會(huì)把符號(hào)引用替換為直接引用,解析的過(guò)程會(huì)去查詢字符串常量池,也就是我們上面所說(shuō)的StringTable,
以保證運(yùn)行時(shí)常量池所引用的字符串與字符串常量池中是一致的。
1.7、直接內(nèi)存
Java使用naive函數(shù)庫(kù)直接分配堆外內(nèi)存,避免了在java堆和native堆中來(lái)回復(fù)制數(shù)據(jù)
2、hotspot虛擬機(jī)
2.1、對(duì)象的創(chuàng)建
如果java虛擬機(jī)的空閑內(nèi)存是連續(xù)的,直接向后挪出一段與對(duì)象大小相等的距離,稱為 指針碰撞
如果不連續(xù),則從剩余內(nèi)存中尋找出足夠大小的內(nèi)存存放,稱 為 空閑列表方式
如何避免線程安全
為每個(gè)線程分配空間
cas配上失敗重試
2.2對(duì)象的內(nèi)存布局
對(duì)象頭:運(yùn)行時(shí)的自身數(shù)據(jù)(哈希碼,gc分代年齡,鎖狀態(tài))、類型指針
實(shí)例數(shù)據(jù):對(duì)象真正存儲(chǔ)的數(shù)據(jù)
對(duì)齊填充:每個(gè)對(duì)象的起始地址必須為8字節(jié)的整數(shù)倍
2.3 對(duì)象的訪問(wèn)定位
句柄訪問(wèn):reference指向句柄池接著再指向具體對(duì)象,避免了對(duì)象的修改而需要修改reference的修改,增加了一次尋址
直接指針定位:直接指向具體對(duì)象,
轉(zhuǎn)載于:https://www.cnblogs.com/karryzhang/p/9607522.html
總結(jié)
以上是生活随笔為你收集整理的java虚拟机 第二章Java内存区域与内存溢出异常的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Eclipse配置关联Tomcat并运行
- 下一篇: RxJava尝试取代Handler初探