jvm知識(shí)點(diǎn)整理

7fa016dea26098cb7ab0b6ec35f04fb.png

內(nèi)存劃分

java虛擬機(jī)\color{red}{在執(zhí)行java程序的過程中}會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域

image.png

程序計(jì)數(shù)器
當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。字節(jié)碼解釋器通過改變這個(gè)計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令
虛擬機(jī)棧
java方法執(zhí)行的內(nèi)存模型岗宣,它的生命周期與線程相同皿曲。方法執(zhí)行時(shí)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表(存放了各種基本數(shù)據(jù)類型boolean设拟、byte缅阳、char、short频敛、int帮哈、float膛檀、long、double娘侍,對(duì)象引用)咖刃、操作棧、動(dòng)態(tài)鏈接憾筏、方法出口等信息嚎杨。
本地方法棧
虛擬機(jī)使用到的nativie方法服務(wù)
Java堆
存放對(duì)象的實(shí)例,幾乎所有對(duì)象都在這里分配內(nèi)存氧腰。棧上分配枫浙、標(biāo)量替換會(huì)導(dǎo)致其他情況
方法區(qū)
用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量古拴、靜態(tài)變量箩帚、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)
運(yùn)行時(shí)常量池,Class文件中除了類的版本黄痪、字段紧帕、方法、接口等之外還有常量池桅打。用于存放編譯期生成的各種字面量和符號(hào)引用
1.8之后叫元空間
運(yùn)行時(shí)常量池
用于存放編譯期生成的各種字面量和符號(hào)引用焕参,String類的intern()

虛擬機(jī)對(duì)象

對(duì)象的創(chuàng)建

1.類加載檢查
虛擬機(jī)遇到一條new指令,會(huì)首先進(jìn)行類加載的檢查:
--檢查這個(gè)指令的參數(shù)是否在常量池中定位到一個(gè)符號(hào)引用
--檢查該類是否被加載油额、解析和初始化,如果沒有就進(jìn)行類加載刻帚。
2.分配內(nèi)存
對(duì)象所需內(nèi)存的大小在類加載完成后便可完全確定潦嘶,于是分配空間等同于把一塊確定大小的內(nèi)存從堆中劃分出來,具體分配方式取決于堆內(nèi)存是否規(guī)整崇众。是否規(guī)整是垃圾收集器是否帶有壓縮整理功能決定的掂僵。
-- 指針碰撞
堆內(nèi)存規(guī)整航厚,移動(dòng)指針
-- 空閑列表
堆內(nèi)存不規(guī)整,虛擬機(jī)維護(hù)記錄可用內(nèi)存的列表锰蓬,從列表中查找對(duì)應(yīng)對(duì)象大小的內(nèi)存區(qū)域分配給對(duì)象幔睬,并更新空閑列表。
為保證內(nèi)存分配時(shí)并發(fā)情況下線程安全問題芹扭,有兩種方案:
-- CAS+失敗重試
虛擬機(jī)采用CAS配上失敗重試的方式保證更新操作的原子性來對(duì)分配內(nèi)存空間的動(dòng)作進(jìn)行同步處理
-- TLAB
把內(nèi)存分配的動(dòng)作按照線程劃分在不同的空間之中進(jìn)行麻顶,即每個(gè)線程在java堆中預(yù)先分配一小塊內(nèi)存

3.初始化
內(nèi)存分配完成后,虛擬機(jī)需要將除對(duì)象頭以外分配到的內(nèi)存空間都初始化為0舱卡,如果使用TLAB,這一工作過程也可以提前至TLAB分配時(shí)進(jìn)行辅肾。這一步操作保證了對(duì)象的實(shí)例字段在java代碼中可以不賦初始值就直接使用,程序能訪問到這些字段的數(shù)據(jù)類型所對(duì)應(yīng)的零值轮锥。

4.設(shè)置對(duì)象頭
初始化零值之后矫钓,虛擬機(jī)要對(duì)對(duì)象進(jìn)行必要的設(shè)置,這些設(shè)置信息存放在對(duì)象的對(duì)象頭Object Header之中舍杜。
對(duì)象頭包括:markword新娜、類型指針、數(shù)組長度

5.執(zhí)行init方法
為對(duì)象屬性復(fù)制既绩,執(zhí)行對(duì)象的構(gòu)造方法

對(duì)象的內(nèi)存布局

對(duì)象訪問(對(duì)象定位)

1.使用句柄
句柄中包含了對(duì)象實(shí)例數(shù)據(jù)和類型數(shù)據(jù)各自的具體地址信息


通過句柄訪問對(duì)象

2.直接指針


通過直接指針訪問對(duì)象

分配對(duì)象

Java 中\color{red}{對(duì)象地址操作}主要使用 Unsafe 調(diào)用了 C 的 allocate 和 free 兩個(gè)方法概龄,分配方法有兩種:
1.指針碰撞: 始終跟蹤上一次分配對(duì)象時(shí)使用的空間末尾地址。當(dāng)要為新對(duì)象分配空間時(shí)熬词,會(huì)在當(dāng)前所處的代的各個(gè)內(nèi)存塊中查找是否有適合大小的空間來分配給新對(duì)象旁钧,若有,則更新指針互拾,初始化對(duì)象

2.空閑列表: 維護(hù)一個(gè)列表歪今,記錄上哪些內(nèi)存可用。

垃圾對(duì)象

1.引用計(jì)數(shù)算法

給對(duì)象中添加一個(gè)引用計(jì)數(shù)器颜矿,每當(dāng)有一個(gè)地方引用它時(shí)寄猩,計(jì)數(shù)器值加1;當(dāng)引用失效時(shí)骑疆,計(jì)數(shù)器值就減1田篇;任何時(shí)刻計(jì)數(shù)器都為0的對(duì)象就是不可能在被使用
缺點(diǎn)就是相互引用

2.根搜索算法

通過“GC Roots”的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索箍铭,搜索所走過的路勁成為引用鏈泊柬,當(dāng)一個(gè)對(duì)象到Gc Roots 沒有任何引用鏈相連,則證明此對(duì)象是不可用的诈火。
Gc Roots對(duì)象包括:

  • 虛擬機(jī)棧(棧幀中的本地變量表)中的引用的對(duì)象
  • 方法區(qū)中的類靜態(tài)屬性引用的對(duì)象
  • 方法區(qū)中的常量引用的對(duì)象
  • 本地方法棧中JNI的引用的對(duì)象
    什么是引用兽赁?
    強(qiáng)引用
    只要強(qiáng)引用還在,垃圾收集器永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象
    軟引用
    在系統(tǒng)將要發(fā)生內(nèi)存溢出異常之前,將會(huì)把這些對(duì)象列進(jìn)回收范圍之中并進(jìn)行第二次回收
    弱引用
    只能生存到下一次來及收集發(fā)生之前刀崖,WeakReference類來實(shí)現(xiàn)弱引用
    虛引用

兩次標(biāo)記過程才會(huì)真正死亡惊科。
第一次標(biāo)記:
判斷是否存在引用鏈。然后篩選(判斷是否有必要執(zhí)行finalize方法)亮钦,并放置F-Queue的隊(duì)列中
第二次標(biāo)記
GC將對(duì)F-Queue中的對(duì)象進(jìn)行第二次小規(guī)模的標(biāo)記

垃圾收集算法

1.標(biāo)記-清除算法
首先標(biāo)記出所有需要回收的對(duì)象馆截,在標(biāo)記完成后統(tǒng)一回收掉所有被標(biāo)記的對(duì)象
缺點(diǎn): 1.效率問題。2.空間問題
2.復(fù)制算法
將可用內(nèi)存按容量劃分為大小相等的兩塊蜂莉,每次只使用其中的一塊蜡娶。當(dāng)這一塊用完了。就將存貨著的對(duì)象復(fù)制到另外一塊上巡语。然后將已使用過的內(nèi)存空間一次清理掉翎蹈。

3.標(biāo)記-整理算法
讓所有存貨的對(duì)象都向一端移動(dòng),然后直接清理掉端邊界以外的內(nèi)存

3.分代收集算法
根據(jù)對(duì)象的存貨周期的不同將內(nèi)存劃分為幾塊男公。一般是把java堆分為新生代和老年代荤堪。這樣可以根據(jù)各個(gè)年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ā?/p>

垃圾收集器

image.png

如果兩個(gè)收集器之間存在連線,說明可以搭配使用枢赔。
Serial收集器
jdk1.3.1之前新生代澄阳,單線程的收集器。收集垃圾時(shí)踏拜,必須暫停其他所有的工作線程
優(yōu)點(diǎn):簡單而高效碎赢,適合client端

ParNew收集器
Serial收集器的多線程版本

Parallel Scavenge收集器
新生代收集器,使用復(fù)制算法并行的多線程收集器速梗。目標(biāo)是達(dá)到一個(gè)可控制的吞吐量
停頓時(shí)間越短就越適合需要與用戶交互的程序肮塞,良好的響應(yīng)速度能提升用戶的體驗(yàn)﹔而高吞吐量則可以最高效率地利用CPU時(shí)間,盡快地完成程序的運(yùn)算任務(wù)姻锁,主要適合在后臺(tái)運(yùn)算而不需要太多交互的任務(wù)枕赵。

Serial Old收集器
老年代版本的單線程收集器。使用“標(biāo)記-整理”算法

Parallel Old收集器
Parallel Old是Parallel Scavenge收集器的老年代版本位隶,使用多線程和“標(biāo)記-整理”算法拷窜。

CMS收集器
是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器〗Щ疲“標(biāo)記-清除”

image.png

優(yōu)點(diǎn):并發(fā)收集篮昧、低停頓
缺陷:對(duì)cpu資源非常敏感、無法處理浮動(dòng)垃圾笋妥、產(chǎn)生大量空間碎片

G1收集器(精準(zhǔn)控制停頓時(shí)間懊昨,避免垃圾碎片)
減少“Stop the world”G1垃圾收集器能同時(shí)回收年輕代和老年代的對(duì)象,它最大的一個(gè)特點(diǎn)是把java堆內(nèi)存拆分為多個(gè)大小相等的region春宣,使得每個(gè)小空間可以單獨(dú)進(jìn)行垃圾回收疚颊。在指定的時(shí)間范圍內(nèi)狈孔,同時(shí)在有限的時(shí)間內(nèi)盡量回收盡可能多的垃圾對(duì)象
維護(hù)了一個(gè)優(yōu)先列表,根據(jù)允許的收集時(shí)間材义,優(yōu)先回收最大的region
G1 收集器兩個(gè)最突出的改進(jìn)是:

【1】基于標(biāo)記-整理算法,不產(chǎn)生內(nèi)存碎片嫁赏。

【2】可以非常精確控制停頓時(shí)間其掂,在不犧牲吞吐量前提下,實(shí)現(xiàn)低停頓垃圾回收潦蝇。(增量回收款熬,不是全量回收)

存放類的信息到元空間

JVM分代模型:年輕代和老年代

對(duì)象的分配機(jī)制

分配機(jī)制

正常情況下是在堆上分配

  • 新生代回收之后,因?yàn)榇婊顚?duì)象太多攘乒,導(dǎo)致大量對(duì)象直接進(jìn)入老年代

  • 特別大的超大對(duì)象直接不經(jīng)過新生代就進(jìn)入老年代
    有一個(gè)JVM參數(shù)贤牛,就是“-XX:PretenureSizeThreshold”,可以把他的值設(shè)置為字節(jié)數(shù)则酝。只要對(duì)象大于這個(gè)參數(shù)殉簸,那么會(huì)直接進(jìn)入老年代。避免對(duì)象在survivor 對(duì)象間頻繁復(fù)制

  • 長期存活的對(duì)象
    虛擬機(jī)給每個(gè)對(duì)象定義了一個(gè)對(duì)象年齡計(jì)數(shù)器沽讹,經(jīng)過一次minorGC后仍然存活般卑,并且被Survivor容納的話,就加一歲爽雄,當(dāng)它的年齡增加到一定程度(默認(rèn)為15歲)蝠检,就將晉升到老年代。
    年齡閾值可通過“-XX:MaxTenuringThreshold”設(shè)置

  • 動(dòng)態(tài)對(duì)象年齡判斷機(jī)制
    年齡1+年齡2+年齡n的多個(gè)年齡對(duì)象總和超過了Survivor區(qū)域的50%挚瘟,此時(shí)就會(huì)把年齡n以上的對(duì)象都放入老年代

  • 空間擔(dān)保機(jī)制
    每一次minor GC 之前叹谁,jvm會(huì)檢查一下老年代可用內(nèi)存空間,是否大于新生代所有對(duì)象的總大小乘盖,假如老年代的內(nèi)存小于新生代的全部對(duì)象大小焰檩,會(huì)看“-XX:-HandlePromotionFailure”的參數(shù)是否設(shè)置了,如果設(shè)置了就判斷老年代的內(nèi)存是否大于之前每一次minor Gc后進(jìn)入老年代的平均對(duì)象大小侧漓。如果小于或者沒有這個(gè)參數(shù)锅尘,那么就會(huì)執(zhí)行full GC。如果執(zhí)行后還是沒有足夠的大小夠放對(duì)象布蔗。那么就會(huì)報(bào)“OOM”

方法區(qū)內(nèi)會(huì)不會(huì)進(jìn)行垃圾回收藤违?

首先該類的所有實(shí)例對(duì)象都已經(jīng)從Java堆內(nèi)存里被回收
其次加載這個(gè)類的ClassLoader已經(jīng)被回收
最后,對(duì)該類的Class對(duì)象沒有任何引用

老年代什么是否觸發(fā)垃圾回收纵揍?

JVM 優(yōu)化之常用參數(shù)
-Xms: 堆最小空間顿乒,建議設(shè)置為物理內(nèi)存的1/4
-Xmx:堆最大空間,建議設(shè)置為物理內(nèi)存的1/2
-XX:NewRatio: Old/New的比例
-Xmn: 年輕代大小泽谨,調(diào)整會(huì)影響老年代大小璧榄,官方建議堆大小的3/8
-XX:SurvivorRatio: 調(diào)整Survivor和Eden的比例大小
-XX:MetaspaceSize: 元空間初始化大小特漩,
-XX:MaxMetaspaceSize: 元空間最大大小
-XX:PretenureSizeThreshold: 大對(duì)象直接進(jìn)入老年代的閾值
-XX:MaxTenuringThreshold: 進(jìn)入老年代的分代年齡閾值

JVM性能調(diào)優(yōu)

常用命令:jps、jinfo骨杂、jstat涂身、jstack、jmap

調(diào)測工具
Arthas

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搓蚪,一起剝皮案震驚了整個(gè)濱河市蛤售,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌妒潭,老刑警劉巖悴能,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異雳灾,居然都是意外死亡漠酿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門谎亩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炒嘲,“玉大人,你說我怎么就攤上這事团驱∶停” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵嚎花,是天一觀的道長寸痢。 經(jīng)常有香客問我,道長紊选,這世上最難降的妖魔是什么啼止? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮兵罢,結(jié)果婚禮上献烦,老公的妹妹穿的比我還像新娘。我一直安慰自己卖词,他們只是感情好巩那,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著此蜈,像睡著了一般即横。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上裆赵,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天东囚,我揣著相機(jī)與錄音,去河邊找鬼战授。 笑死页藻,一個(gè)胖子當(dāng)著我的面吹牛桨嫁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播份帐,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼璃吧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弥鹦?” 一聲冷哼從身側(cè)響起肚逸,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎彬坏,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膝晾,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡栓始,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了血当。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幻赚。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖臊旭,靈堂內(nèi)的尸體忽然破棺而出落恼,到底是詐尸還是另有隱情,我是刑警寧澤离熏,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布佳谦,位于F島的核電站,受9級(jí)特大地震影響滋戳,放射性物質(zhì)發(fā)生泄漏钻蔑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一奸鸯、第九天 我趴在偏房一處隱蔽的房頂上張望咪笑。 院中可真熱鬧,春花似錦娄涩、人聲如沸窗怒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扬虚。三九已至,卻和暖如春弯蚜,著一層夾襖步出監(jiān)牢的瞬間孔轴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工碎捺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留路鹰,地道東北人贷洲。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像晋柱,于是被迫代替她去往敵國和親优构。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容