一孟害。程序計數(shù)器
java線程私有的喇喉,類似于操作系統(tǒng)里的PC計數(shù)器承粤,可以看做是當前線程所執(zhí)行的字節(jié)碼的行號指示器虑乖。
如果線程正在執(zhí)行的是一個java方法懦趋,這個計數(shù)器記錄的正在執(zhí)行的虛擬機字節(jié)碼指令的地址。
如果正在執(zhí)行的是native方法疹味,這個計數(shù)器值則為空仅叫。 undefined
此內(nèi)存區(qū)域是唯一一個在java虛擬規(guī)范中沒有規(guī)定任何OutOfMemoryError情況的區(qū)域
二。虛擬機棧(棧內(nèi)存)
java線程私有糙捺,虛擬機棧描述的是java方法執(zhí)行的內(nèi)存模型诫咱。
每個方法在執(zhí)行的時候,都會創(chuàng)建一個棧幀用于存儲局部變量洪灯、操作數(shù)坎缭、動態(tài)鏈接、方法出口等信息签钩。
每個方法調(diào)用都意味著一個棧幀在虛擬機棧中入棧到出棧的過程掏呼。
三、本地方法棧
和java虛擬機棧的作用類似铅檩。區(qū)別是該區(qū)域為JVM提供使用Native方法的服務(wù)憎夷。
四、堆內(nèi)存
所有線程共享的一塊區(qū)域昧旨,垃圾回收器管理的主要區(qū)域拾给。
目前主要垃圾回收算法都是分代收集算法,所以java堆中還可以細分為:新生代和老年代兔沃,再細致一點的還有eden區(qū)蒋得,from survivor、to survivor粘拾,默認情況下是8:1:1的比例窄锅。
根據(jù)java虛擬機規(guī)范的規(guī)定,java堆可以處于物理上不連續(xù)的內(nèi)存空間中缰雇,只要邏輯上是連續(xù)的即可入偷,就像我們的磁盤一樣。
五械哟、方法區(qū)
各個線程共享的一個區(qū)域疏之,用于存儲虛擬機加載的類信息,常量暇咆、靜態(tài)變量锋爪,即時編譯器編譯后的代碼等數(shù)據(jù)丙曙。
雖然虛擬機規(guī)范中把方法區(qū)描述成堆的一個邏輯部分,但是他卻有一個別名叫Non-heap 非堆其骄,目的是為了與java堆區(qū)分開來亏镰。
運行時常量池。是方法區(qū)的一部分拯爽,用于存放編譯器生成的各種字面量和符號引用索抓。
直接內(nèi)存
direct memory,并不是虛擬機運行時數(shù)據(jù)區(qū)的一部分毯炮,也不是java虛擬機規(guī)范中定義的內(nèi)存區(qū)域逼肯。在1.4中新加入的NIO類,引入了一種基于通道Channel與緩沖區(qū)Buffer的IO方式桃煎,它可以使用native函數(shù)庫直接分配堆外內(nèi)存篮幢,
然后通過一個存儲在java堆中的DirectByteBuffer對象作為這塊內(nèi)存的引用進行操作。這樣能在一些場景中顯著提高性能为迈,因為避免了在java堆和Nativa堆中來回復(fù)制數(shù)據(jù)三椿。
本機直接內(nèi)存的分配不會受到Java堆大小的限制,受到本機總內(nèi)存的大小限制曲尸。配置虛擬機參數(shù)時赋续,不要忽略直接內(nèi)存,防止出現(xiàn)OOM異常另患。
比較
直接內(nèi)存申請空間耗費更高的性能纽乱,當頻繁申請到一定量時尤為明顯。
直接內(nèi)存IO 讀寫的性能要優(yōu)于普通的堆內(nèi)存昆箕,在多次讀寫操作的情況下差異明顯鸦列。
后續(xù)發(fā)展
JDK7:
存儲在永久代的部分數(shù)據(jù)轉(zhuǎn)移到了JVM heap或者是Native heap中。
JDK8:
廢棄了永久代PermGen鹏倘,新增Metaspace元數(shù)據(jù)區(qū)
方法區(qū)在Metaspace中了薯嗤。
MetaSpace大小默認沒有限制,一般根據(jù)系統(tǒng)內(nèi)存的大小纤泵,jvm會動態(tài)改變此值骆姐。
可以通過jvm參數(shù)配置:
-XX:MetaspaceSize 分配給類元數(shù)據(jù)空間(以字節(jié)計算)的初始大小。MetaspaceSize的值設(shè)置的太大會延長垃圾回收時間捏题,垃圾
回收過后玻褪,引起下一次垃圾回收的類元數(shù)據(jù)空間的大小可能會變大。
-XX:MaxMteaspaceSize:分配給類元數(shù)據(jù)空間的最大值公荧,超過此值就會觸發(fā)FullGC带射,此值默認沒有限制,但應(yīng)取決于系統(tǒng)內(nèi)存的大小循狰,JVM會動態(tài)改變此值窟社。
個人博客
騰訊云社區(qū)
掘金
CSDN
OSCHINA
公眾號: