jvm 架構(gòu)及調(diào)優(yōu)

jvm 架構(gòu)及優(yōu)化

寫(xiě)在前面

先看一下知乎上一個(gè)有趣的問(wèn)題:

Java工程師面試的時(shí)候,總是提問(wèn)一些jvm如何優(yōu)化的問(wèn)題质礼,這些真的在開(kāi)發(fā)中有用嗎兔院,工作七年了項(xiàng)目中從來(lái)沒(méi)有用過(guò)零聚,并且我獲得過(guò)多次優(yōu)秀員工,望做過(guò)優(yōu)化的大牛解答?

答一:
JVM優(yōu)化肯定是有用的煎谍,可能只是題主沒(méi)有遇到過(guò)這方面的需求攘蔽。比如一些GC機(jī)制會(huì)引起JVM的Stop The World,也就是所有工作線程都會(huì)停下來(lái)等待GC完成呐粘。對(duì)于一些對(duì)延遲比較敏感的程序來(lái)說(shuō)满俗,這一停頓達(dá)到一百甚至是幾十毫秒的時(shí)候就是難以接受的。為了解決這類(lèi)問(wèn)題事哭,就需要對(duì)JVM的參數(shù)做適當(dāng)?shù)恼{(diào)整漫雷。比如調(diào)整堆的大小,選擇合適的垃圾回收器鳍咱,控制對(duì)象晉升老年代的速度等等降盹。

作者:謝知恒

鏈接:https://www.zhihu.com/question/40913700/answer/88862720

來(lái)源:知乎

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)谤辜,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處蓄坏。

答二:
對(duì)于樓主這種情況也是可以理解的价捧,以前我在傳統(tǒng)行業(yè)做行業(yè)軟件的時(shí)候也是對(duì)jvm一無(wú)所知,覺(jué)得一點(diǎn)用沒(méi)有涡戳,面試問(wèn)只是裝逼而已结蟋。后來(lái)踏入互聯(lián)網(wǎng)行業(yè)才明白,這是必須掌握的渔彰,而且經(jīng)常會(huì)用嵌屎,遇到tp99間斷性的提高,這種情況首先就會(huì)去看是否是fullGC引起的恍涂,還有就是內(nèi)存溢出之類(lèi)的問(wèn)題宝惰,不了解jvm怎么去解決這類(lèi)問(wèn)題。當(dāng)然傳統(tǒng)行業(yè)軟件再沧,用戶量少可能不會(huì)去監(jiān)控性能尼夺,遇到內(nèi)存溢出可能也就重啟解決了,不了了之炒瘸,下次再重啟淤堵。然而,對(duì)于java開(kāi)發(fā)人員來(lái)說(shuō)顷扩,jvm就是一座商廈拐邪,我們?cè)诶锩骈_(kāi)店,連消防栓在哪里都不知道屎即,哪天著火了庙睡,應(yīng)急樓梯也不知道在哪里事富,只能坐著哭技俐?所以還是建議樓主了解一下jvm,推薦看《深入理解java虛擬機(jī)》

作者:周易

鏈接:https://www.zhihu.com/question/40913700/answer/138011891

來(lái)源:知乎

著作權(quán)歸作者所有统台。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)雕擂,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

從上面兩段回答中可以看出來(lái)贱勃,熟悉jvm架構(gòu)和調(diào)優(yōu)意義在于出了性能問(wèn)題后井赌,多給程序員留了一條退路。

jvm 架構(gòu)

jvm架構(gòu)

首先先附上一張jvm架構(gòu)圖贵扰。
上圖中主要由幾個(gè)部分組成:

  • 類(lèi)加載器(ClassLoader):在JVM啟動(dòng)時(shí)或者在類(lèi)運(yùn)行時(shí)將需要的class加載到JVM中仇穗。每當(dāng)運(yùn)行一個(gè)
    java 程序時(shí),就會(huì)首先動(dòng)態(tài)創(chuàng)建相應(yīng)的jvm instance(啟動(dòng)三個(gè)程序戚绕,就會(huì)有三個(gè)jvm實(shí)例纹坐,這點(diǎn)和golang runtime非常類(lèi)似),然后將該程序的所有類(lèi)文件通過(guò)類(lèi)加載器加載到j(luò)vm中舞丛。
  • 執(zhí)行引擎:負(fù)責(zé)執(zhí)行class文件中包含的字節(jié)碼指令.執(zhí)行引擎是java 虛擬機(jī)模擬運(yùn)行的運(yùn)算引擎耘子,基本起到了翻譯的作用果漾。
    有兩種翻譯的方式:
    • 一句話一句話翻譯。也就是解釋執(zhí)行谷誓。將程序計(jì)算器中指向的待執(zhí)行的java字節(jié)碼翻譯為cpu可以運(yùn)行的機(jī)器指令绒障。
    • 一次性翻譯。即編譯執(zhí)行捍歪。通過(guò)JIT(just in time)一次性將所有的字節(jié)碼翻譯完成户辱。
  • 內(nèi)存區(qū)(也叫運(yùn)行時(shí)數(shù)據(jù)區(qū)):是在JVM運(yùn)行的時(shí)候操作所分配的內(nèi)存區(qū)。從上圖中可以看出糙臼,主要分為五個(gè)部分焕妙。
  • 本地庫(kù)接口,本地方法庫(kù):操作系統(tǒng)所有弓摘,用于處理jvm的native code和通過(guò)jit編譯后的本地代碼焚鹊。

jvm 執(zhí)行引擎

關(guān)于jvm的執(zhí)行引擎,它并不是真正軟件模擬實(shí)現(xiàn)了cpu韧献,最終所有計(jì)算機(jī)上的運(yùn)算都是由cpu執(zhí)行機(jī)器指令來(lái)處理末患。

有個(gè)問(wèn)題?jvm執(zhí)行引擎和本地代碼關(guān)系如何锤窑?本地代碼還需要過(guò)jvm執(zhí)行引擎嗎璧针?

猜測(cè)答案:應(yīng)該是需要過(guò)的,jvm封裝了所有的代碼渊啰,管理著程序執(zhí)行的結(jié)果探橱。

關(guān)于執(zhí)行引擎采用哪種方式來(lái)運(yùn)行,經(jīng)驗(yàn)如下:

用JIT編譯器來(lái)編譯代碼所花的時(shí)間要比用解釋器去一條條解釋執(zhí)行花的時(shí)間要多绘证。因此隧膏,如果代碼只被執(zhí)行一次的話,那么最好還是解釋執(zhí)行而不是編譯后再執(zhí)行嚷那。因此胞枕,內(nèi)置了JIT編譯器的JVM都會(huì)檢查方法的執(zhí)行頻率,如果一個(gè)方法的執(zhí)行頻率超過(guò)一個(gè)特定的值的話魏宽,那么這個(gè)方法就會(huì)被編譯成本地代碼腐泻。

jvm 內(nèi)存

從jvm 架構(gòu)可以看出,jvm內(nèi)存主要分為五部分:

  • 方法區(qū)(Method Area):用于存儲(chǔ)類(lèi)結(jié)構(gòu)信息的地方队询,包括常量池派桩、靜態(tài)變量、構(gòu)造函數(shù)等蚌斩。雖然JVM規(guī)范把方法區(qū)描述為堆的一個(gè)邏輯部分铆惑, 但它卻有個(gè)別名non-heap(非堆),所以大家不要搞混淆了。方法區(qū)還包含一個(gè)運(yùn)行時(shí)常量池鸭津。
  • java堆(Heap):存儲(chǔ)java實(shí)例或者對(duì)象的地方彤侍。這塊是GC的主要區(qū)域。從存儲(chǔ)的內(nèi)容我們可以很容易知道逆趋,方法區(qū)和堆是被所有java線程共享的盏阶。
  • java棧(Stack):java棧總是和線程關(guān)聯(lián)在一起闻书,每當(dāng)創(chuàng)建一個(gè)線程時(shí)名斟,JVM就會(huì)為這個(gè)線程創(chuàng)建一個(gè)對(duì)應(yīng)的java棧。在這個(gè)java棧中又會(huì)包含多個(gè)棧幀魄眉,每運(yùn)行一個(gè)方法就創(chuàng)建一個(gè)棧幀砰盐,用于存儲(chǔ)局部變量表、操作棧坑律、方法返回值等岩梳。每一個(gè)方法從調(diào)用直至執(zhí)行完成的過(guò)程,就對(duì)應(yīng)一個(gè)棧幀在java棧中入棧到出棧的過(guò)程晃择。所以java棧是現(xiàn)成私有的冀值。
  • 程序計(jì)數(shù)器(PC Register):用于保存當(dāng)前線程執(zhí)行的內(nèi)存地址。由于JVM程序是多線程執(zhí)行的(線程輪流切換)宫屠,所以為了保證線程切換回來(lái)后列疗,還能恢復(fù)到原先狀態(tài),就需要一個(gè)獨(dú)立的計(jì)數(shù)器浪蹂,記錄之前中斷的地方抵栈,可見(jiàn)程序計(jì)數(shù)器也是線程私有的。
  • 本地方法棧(Native Method Stack):和java棧的作用差不多坤次,只不過(guò)是為JVM使用到的native方法服務(wù)的古劲。

java 堆存放對(duì)象實(shí)例。
java 棧存放普通的變量及其它類(lèi)型的信息浙踢。
這樣的好處是對(duì)象通常占有內(nèi)存很大绢慢,但個(gè)數(shù)少灿渴。棧里存放的東西個(gè)數(shù)多洛波,占用內(nèi)存少。對(duì)象是垃圾回收的主戰(zhàn)場(chǎng)骚露。
所以要分出棧和堆來(lái)蹬挤。

jvm調(diào)優(yōu)

傳統(tǒng)的軟件開(kāi)發(fā)過(guò)程中不需要考慮到j(luò)vm調(diào)優(yōu)的內(nèi)容,主要出于以下的幾點(diǎn)考慮:

  • 性能不是生命線棘幸。
  • 系統(tǒng)出問(wèn)題后可以采取其它的方式進(jìn)行處理焰扳,例如停機(jī),停機(jī)后再恢復(fù),受影響不大吨悍。

而在互聯(lián)網(wǎng)領(lǐng)域扫茅,上述兩個(gè)問(wèn)題就變?yōu)楸容^嚴(yán)重的問(wèn)題。
為了留住用戶育瓜,響應(yīng)時(shí)間和吞吐量就會(huì)成為必須去解決的問(wèn)題葫隙。而jvm性能瓶頸主要在與jvm自帶的垃圾回收機(jī)制。

內(nèi)存分配機(jī)制

靜態(tài)內(nèi)存&動(dòng)態(tài)內(nèi)存

Java的內(nèi)存分配原理與C/C++不同躏仇,C/C++每次申請(qǐng)內(nèi)存時(shí)都要malloc進(jìn)行系統(tǒng)調(diào)用恋脚,而系統(tǒng)調(diào)用發(fā)生在內(nèi)核空間,每次都要中斷進(jìn)行切換焰手,這需要一定的開(kāi)銷(xiāo)糟描,

而Java虛擬機(jī)是先一次性分配一塊較大的空間,然后每次new時(shí)都在該空間上進(jìn)行分配和釋放书妻,減少了系統(tǒng)調(diào)用的次數(shù)船响,節(jié)省了一定的開(kāi)銷(xiāo),這有點(diǎn)類(lèi)似于內(nèi)存池的概念躲履;二是有了這塊空間過(guò)后灿意,如何進(jìn)行分配和回收就跟GC機(jī)制有關(guān)了。

java一般內(nèi)存申請(qǐng)有兩種:

  • 靜態(tài)內(nèi)存.編譯時(shí)就能夠確定的內(nèi)存就是靜態(tài)內(nèi)存崇呵,即內(nèi)存是固定的缤剧,系統(tǒng)一次性分配,比如int類(lèi)型變量域慷;java棧荒辕、程序計(jì)數(shù)器、本地方法棧都是線程私有的犹褒,線程生就生抵窒,線程滅就滅,棧中的棧幀隨著方法的結(jié)束也會(huì)撤銷(xiāo)叠骑,內(nèi)存自然就跟著回收了李皇。我們不需要管的。
  • 動(dòng)態(tài)內(nèi)存宙枷。動(dòng)態(tài)內(nèi)存分配就是在程序執(zhí)行時(shí)才知道要分配的存儲(chǔ)空間大小掉房,比如java對(duì)象的內(nèi)存空間。所以這幾個(gè)區(qū)域的內(nèi)存分配與回收是確定的慰丛,但是java堆和方法區(qū)則不一樣卓囚,我們只有在程序運(yùn)行期間才知道會(huì)創(chuàng)建哪些對(duì)象,所以這部分內(nèi)存的分配和回收都是動(dòng)態(tài)的诅病。一般我們所說(shuō)的垃圾回收也是針對(duì)的這一部分哪亿。

總之Stack的內(nèi)存管理是順序分配的粥烁,而且定長(zhǎng),不存在內(nèi)存回收問(wèn)題蝇棉;而Heap 則是為java對(duì)象的實(shí)例隨機(jī)分配內(nèi)存讨阻,不定長(zhǎng)度,所以存在內(nèi)存分配和回收的問(wèn)題篡殷;

新生代&老生代

在 Java 中变勇,堆被劃分成兩個(gè)不同的區(qū)域:

  • 新生代 ( Young )。 生命周期較短贴唇。
  • 老年代 ( Old )搀绣。生命周期較長(zhǎng)。
  • 永久代戳气。很少被討論链患。

新生代 ( Young ) 又被劃分為三個(gè)區(qū)域:

  • Eden
  • From Survivor
  • To Survivor。

GC機(jī)制簡(jiǎn)述

JVM 使用的GC算法是什么瓶您?

分代收集:即將內(nèi)存分為幾個(gè)區(qū)域麻捻,將不同生命周期的對(duì)象放在不同區(qū)域里。GC根據(jù)用途來(lái)說(shuō)有以下三種:

  • GC(或Minor GC):收集 生命周期短的區(qū)域(Young area)呀袱。Minor GC會(huì)把Eden中的所有活的對(duì)象都移到Survivor區(qū)域中贸毕,如果Survivor區(qū)中放不下,那么剩下的活的對(duì)象就被移到Old generation 中夜赵。

  • Full GC (或Major GC):基于標(biāo)記-清除算法明棍,收集生命周期短的區(qū)域(Young area)和生命周期比較長(zhǎng)的區(qū)域(Old area)對(duì)整個(gè)堆進(jìn)行垃圾收集。

  • Major GC :清理永久代寇僧。

GC 效率也會(huì)比較高摊腋,我們要盡量減少 Full GC 的次數(shù)。

在minor Gc 與Full Gc執(zhí)行機(jī)制上嘁傀,都提供了三種選擇:

  • 串行GC(SerialGC)
  • 并行回收GC(ParallelScavenge
  • 并行GC(ParNew)

可以根據(jù)具體的需要選擇相應(yīng)的GC兴蒸。

GC的調(diào)整是在吞吐量和響應(yīng)時(shí)間上做一個(gè)平衡。

jvm調(diào)優(yōu)簡(jiǎn)述與工具

怎樣調(diào)優(yōu)?
有何工具?
Jvm調(diào)優(yōu)工具有以下幾種:

  • Jconsole : jdk自帶细办,功能簡(jiǎn)單橙凳,但是可以在系統(tǒng)有一定負(fù)荷的情況下使用。對(duì)垃圾回收算法有很詳細(xì)的跟蹤笑撞。詳細(xì)說(shuō)明參考這里
  • JProfiler:商業(yè)軟件岛啸,需要付費(fèi)。功能強(qiáng)大娃殖。詳細(xì)說(shuō)明參考這里
  • VisualVM:JDK自帶值戳,功能強(qiáng)大,與JProfiler類(lèi)似炉爆。推薦。

關(guān)于調(diào)優(yōu)這塊在實(shí)際業(yè)務(wù)中碰到這類(lèi)的問(wèn)題再進(jìn)行具體分析。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芬首,一起剝皮案震驚了整個(gè)濱河市赴捞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌郁稍,老刑警劉巖赦政,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異耀怜,居然都是意外死亡恢着,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)财破,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)掰派,“玉大人,你說(shuō)我怎么就攤上這事左痢∶蚁郏” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵俊性,是天一觀的道長(zhǎng)略步。 經(jīng)常有香客問(wèn)我,道長(zhǎng)定页,這世上最難降的妖魔是什么趟薄? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮典徊,結(jié)果婚禮上竟趾,老公的妹妹穿的比我還像新娘。我一直安慰自己宫峦,他們只是感情好岔帽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著导绷,像睡著了一般犀勒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妥曲,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天贾费,我揣著相機(jī)與錄音,去河邊找鬼檐盟。 笑死褂萧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的葵萎。 我是一名探鬼主播导犹,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼唱凯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了谎痢?” 一聲冷哼從身側(cè)響起磕昼,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎节猿,沒(méi)想到半個(gè)月后票从,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滨嘱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年峰鄙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片太雨。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吟榴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出躺彬,到底是詐尸還是另有隱情煤墙,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布宪拥,位于F島的核電站仿野,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏她君。R本人自食惡果不足惜脚作,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缔刹。 院中可真熱鬧球涛,春花似錦、人聲如沸校镐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鸟廓。三九已至从祝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間引谜,已是汗流浹背牍陌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留员咽,地道東北人毒涧。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像贝室,于是被迫代替她去往敵國(guó)和親契讲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子仿吞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

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