深入理解JVM虛擬機(jī)

自動(dòng)內(nèi)存管理機(jī)制

Java虛擬機(jī)原理

所謂虛擬機(jī)揉忘,就是一臺(tái)虛擬的機(jī)器破停。他是一款軟件陷嘴,用來執(zhí)行一系列虛擬計(jì)算指令,大體上虛擬機(jī)可以分為

系統(tǒng)虛擬機(jī)和程序虛擬機(jī)摔竿, 大名鼎鼎的Visual Box面粮、Vmare就屬于系統(tǒng)虛擬機(jī),他們完全是對物理計(jì)算的仿真继低,

提供了一個(gè)可以運(yùn)行完整操作系統(tǒng)的軟件平臺(tái)熬苍。

程序虛擬機(jī)典型代碼就是Java虛擬機(jī),它專門為執(zhí)行單個(gè)計(jì)算程序而計(jì)算袁翁,在Java虛擬機(jī)中執(zhí)行的指令我們成為Java

自己碼指令柴底。無論是系統(tǒng)虛擬機(jī)還是程序虛擬機(jī),在上面運(yùn)行的軟件都被限制于虛擬機(jī)提供的資源中粱胜。

Java發(fā)展至今柄驻,出現(xiàn)過很多虛擬機(jī),做初Sun使用的一款叫ClassIc的Java虛擬機(jī)焙压,到現(xiàn)在引用最廣泛的是HotSpot虛擬

機(jī)凿歼,除了Sum意外,還有BEA的Jrockit冗恨,目前Jrockit和HostSopt都被oralce收入旗下,大有整合的趨勢味赃。

Java內(nèi)存結(jié)構(gòu)

1掀抹、 類加載子系統(tǒng):負(fù)責(zé)從文件系統(tǒng)或者網(wǎng)絡(luò)加載Class信息,加載的信息存放在一塊稱之方法區(qū)的內(nèi)存空間心俗。

2傲武、 方法區(qū):就是存放類的信息、常量信息城榛、常量池信息揪利、包括字符串字面量和數(shù)字常量等。

3狠持、 Java堆:在Java虛擬機(jī)啟動(dòng)的時(shí)候建立Java堆疟位,它是Java程序最主要的內(nèi)存工作區(qū)域,幾乎所有的對象實(shí)例都存放到

Java堆中喘垂,堆空間是所有線程共享甜刻。

4、 直接內(nèi)存:JavaNio庫允許Java程序直接內(nèi)存正勒,從而提高性能得院,通常直接內(nèi)存速度會(huì)優(yōu)于Java堆。讀寫頻繁的場合可能會(huì)考慮使用章贞。

5祥绞、 每個(gè)虛擬機(jī)線程都有一個(gè)私有棧,一個(gè)線程的Java棧在線程創(chuàng)建的時(shí)候被創(chuàng)建,Java棧保存著局部變量蜕径、方法參數(shù)两踏、同事Java的方法調(diào)用、

返回值等丧荐。

6缆瓣、 本地方法棧,最大不同為本地方法棧用于本地方法調(diào)用虹统。Java虛擬機(jī)允許Java直接調(diào)用本地方法(通過使用C語言寫)

7弓坞、 垃圾收集系統(tǒng)是Java的核心,也是不可少的车荔,Java有一套自己進(jìn)行垃圾清理的機(jī)制渡冻,開發(fā)人員無需手工清理,下一節(jié)課詳細(xì)講忧便。

8族吻、 PC(Program Couneter)寄存器也是每個(gè)線程私有的空間, Java虛擬機(jī)會(huì)為每個(gè)線程創(chuàng)建PC寄存器珠增,在任意時(shí)刻超歌,

一個(gè)Java線程總是在執(zhí)行一個(gè)方法,這個(gè)方法稱為當(dāng)前方法蒂教,如果當(dāng)前方法不是本地方法巍举,PC寄存器總會(huì)執(zhí)行當(dāng)前正在被執(zhí)行的指令,

如果是本地方法凝垛,則PC寄存器值為Underfined懊悯,寄存器存放如果當(dāng)前執(zhí)行環(huán)境指針、程序技術(shù)器梦皮、操作棧指針炭分、計(jì)算的變量指針等信息。

9剑肯、 虛擬機(jī)核心的組件就是執(zhí)行引擎捧毛,它負(fù)責(zé)執(zhí)行虛擬機(jī)的字節(jié)碼,一般戶先進(jìn)行編譯成機(jī)器碼后執(zhí)行退子。

堆岖妄、棧、方法區(qū)概念區(qū)別

Java堆

堆內(nèi)存用于存放由new創(chuàng)建的對象和數(shù)組寂祥。在堆中分配的內(nèi)存荐虐,由java虛擬機(jī)自動(dòng)垃圾回收器來管理。在堆中產(chǎn)生了一個(gè)數(shù)組或者對象后丸凭,還可以在棧中定義一個(gè)特殊的變量福扬,這個(gè)變量的取值等于數(shù)組或者對象在堆內(nèi)存中的首地址腕铸,在棧中的這個(gè)特殊的變量就變成了數(shù)組或者對象的引用變量,以后就可以在程序中使用棧內(nèi)存中的引用變量來訪問堆中的數(shù)組或者對象铛碑,引用變量相當(dāng)于為數(shù)組或者對象起的一個(gè)別名狠裹,或者代號。

根據(jù)垃圾回收機(jī)制的不同汽烦,Java堆有可能擁有不同的結(jié)構(gòu)涛菠,最為常見的就是將整個(gè)Java堆分為

新生代和老年代。其中新聲帶存放新生的對象或者年齡不大的對象撇吞,老年代則存放老年對象俗冻。

新生代分為den區(qū)、s0區(qū)牍颈、s1區(qū)迄薄,s0和s1也被稱為from和to區(qū)域,他們是兩塊大小相等并且可以互相角色的空間煮岁。

絕大多數(shù)情況下讥蔽,對象首先分配在eden區(qū),在新生代回收后画机,如果對象還存活冶伞,則進(jìn)入s0或s1區(qū),之后每經(jīng)過一次

新生代回收步氏,如果對象存活則它的年齡就加1碰缔,對象達(dá)到一定的年齡后,則進(jìn)入老年代戳护。

Java棧

Java棧是一塊線程私有的空間,一個(gè)棧瀑焦,一般由三部分組成:局部變量表腌且、操作數(shù)據(jù)棧和幀數(shù)據(jù)區(qū)

局部變量表:用于報(bào)錯(cuò)函數(shù)的參數(shù)及局部變量

操作數(shù)棧:主要保存計(jì)算過程的中間結(jié)果,同時(shí)作為計(jì)算過程中的變量臨時(shí)的存儲(chǔ)空間榛瓮。

幀數(shù)據(jù)區(qū):除了局部變量表和操作數(shù)據(jù)棧以外铺董,棧還需要一些數(shù)據(jù)來支持常量池的解析,這里幀數(shù)據(jù)區(qū)保存著

訪問常量池的指針禀晓,方便計(jì)程序訪問常量池精续,另外當(dāng)函數(shù)返回或出現(xiàn)異常時(shí)賣虛擬機(jī)子必須有一個(gè)異常處理表,方便發(fā)送異常

的時(shí)候找到異常的代碼粹懒,因此異常處理表也是幀數(shù)據(jù)區(qū)的一部分重付。

Java方法區(qū)

Java方法區(qū)和堆一樣,方法區(qū)是一塊所有線程共享的內(nèi)存區(qū)域凫乖,他保存系統(tǒng)的類信息确垫。

比如類的字段弓颈、方法、常量池等删掀。方法區(qū)的大小決定系統(tǒng)可以保存多少個(gè)類翔冀。如果系統(tǒng)

定義太多的類,導(dǎo)致方法區(qū)溢出披泪。虛擬機(jī)同樣會(huì)拋出內(nèi)存溢出的錯(cuò)誤纤子。方法區(qū)可以理解

為永久區(qū)。

虛擬機(jī)參數(shù)配置

什么是虛擬機(jī)參數(shù)配置

在虛擬機(jī)運(yùn)行的過程中款票,如果可以跟蹤系統(tǒng)的運(yùn)行狀態(tài)控硼,那么對于問題的故障

排查會(huì)有一定的幫助,為此徽职,在虛擬機(jī)提供了一些跟蹤系統(tǒng)狀態(tài)的參數(shù)象颖,使用

給定的參數(shù)執(zhí)行Java虛擬機(jī),就可以在系統(tǒng)運(yùn)行時(shí)打印相關(guān)日志姆钉,用于分析實(shí)際

問題说订。我們進(jìn)行虛擬機(jī)參數(shù)配置,其實(shí)就是圍繞著堆潮瓶、棧陶冷、方法區(qū)、進(jìn)行配置毯辅。

你說下 你熟悉那些jvm參數(shù)調(diào)優(yōu)

堆的參數(shù)配置

-XX:+PrintGC 每次觸發(fā)GC的時(shí)候打印相關(guān)日志

-XX:+UseSerialGC 串行回收

-XX:+PrintGCDetails 更詳細(xì)的GC日志

-Xms 堆初始值

-Xmx 堆最大可用值

-Xmn 新生代堆最大可用值

-XX:SurvivorRatio 用來設(shè)置新生代中eden空間和from/to空間的比例.

含以-XX:SurvivorRatio=eden/from=den/to

總結(jié):在實(shí)際工作中埂伦,我們可以直接將初始的堆大小與最大堆大小相等,

這樣的好處是可以減少程序運(yùn)行時(shí)垃圾回收次數(shù)思恐,從而提高效率沾谜。

-XX:SurvivorRatio 用來設(shè)置新生代中eden空間和from/to空間的比例.

設(shè)置最大堆內(nèi)存

參數(shù): -Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags

設(shè)置新生代與老年代優(yōu)化參數(shù)

-Xmn 新生代大小,一般設(shè)為整個(gè)堆的1/3到1/4左右

-XX:SurvivorRatio 設(shè)置新生代中eden區(qū)和from/to空間的比例關(guān)系n/1

設(shè)置新生代比例參數(shù)

參數(shù): -Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC

設(shè)置新生與老年代代參數(shù)

-Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC

-Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC

-XX:NewRatio=2

總結(jié):不同的堆分布情況胀莹,對系統(tǒng)執(zhí)行會(huì)產(chǎn)生一定的影響基跑,在實(shí)際工作中,

應(yīng)該根據(jù)系統(tǒng)的特點(diǎn)做出合理的配置描焰,基本策略:盡可能將對象預(yù)留在新生代媳否,

減少老年代的GC次數(shù)。

除了可以設(shè)置新生代的絕對大小(-Xmn),可以使用(-XX:NewRatio)設(shè)置新生代和老年

代的比例:-XX:NewRatio=老年代/新生代

內(nèi)存溢出解決辦法

設(shè)置堆內(nèi)存大小

錯(cuò)誤原因: java.lang.OutOfMemoryError: Java heap space

解決辦法:設(shè)置堆內(nèi)存大小 -Xms1m -Xmx70m -XX:+HeapDumpOnOutOfMemoryError

設(shè)置棧內(nèi)存大小

錯(cuò)誤原因: java.lang.StackOverflowError

棧溢出 產(chǎn)生于遞歸調(diào)用荆秦,循環(huán)遍歷是不會(huì)的篱竭,但是循環(huán)方法里面產(chǎn)生遞歸調(diào)用, 也會(huì)發(fā)生棧溢出步绸。

解決辦法:設(shè)置線程最大調(diào)用深度

-Xss5m 設(shè)置最大調(diào)用深度

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掺逼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瓤介,更是在濱河造成了極大的恐慌坪圾,老刑警劉巖晓折,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異兽泄,居然都是意外死亡漓概,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門病梢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胃珍,“玉大人,你說我怎么就攤上這事蜓陌∶僬茫” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵钮热,是天一觀的道長填抬。 經(jīng)常有香客問我,道長隧期,這世上最難降的妖魔是什么飒责? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮仆潮,結(jié)果婚禮上宏蛉,老公的妹妹穿的比我還像新娘。我一直安慰自己性置,他們只是感情好拾并,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鹏浅,像睡著了一般嗅义。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上隐砸,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天芥喇,我揣著相機(jī)與錄音,去河邊找鬼凰萨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛械馆,可吹牛的內(nèi)容都是我干的胖眷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼霹崎,長吁一口氣:“原來是場噩夢啊……” “哼珊搀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起尾菇,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤境析,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后劳淆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡括勺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了曲掰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疾捍。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡栏妖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吊趾,到底是詐尸還是另有隱情宛裕,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布趾徽,位于F島的核電站续滋,受9級特大地震影響孵奶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜了袁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一载绿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧崭庸,春花似錦怀浆、人聲如沸怕享。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跌帐。三九已至绊率,卻和暖如春究履,著一層夾襖步出監(jiān)牢的瞬間滤否,已是汗流浹背挎袜。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工盯仪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人全景。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像爸黄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子梆奈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

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

  • # 很英范兒的表達(dá)方式與美式的幽默略有不同称开。英式幽默的笑點(diǎn)通暢比較隱晦,多帶點(diǎn)諷刺鳖轰,也經(jīng)常自嘲,而且最重要的一點(diǎn)是...
    小王加油啊閱讀 1,625評論 0 3
  • 混沌的天和地 嘶啞了口 夸父逐著太陽 遁入黑暗 河水中的魚兒 躍了龍門 折損 后羿失去了弓和箭 與太陽一同 毀滅 ...
    趙稚生閱讀 232評論 0 0
  • 深夜 突兀的廣播 把人們從睡夢中叫醒 極不情愿,以為又要廣播廣告 農(nóng)藥昆雀,種子,化肥狞膘! 廣播者清了清喉嚨, 捎帶著給...
    夜雨歌者閱讀 114評論 0 2
  • 最近在看動(dòng)畫的使用。在看Android官方文檔時(shí)稳强,看到觸摸反饋的文章和悦,就自己動(dòng)手實(shí)驗(yàn)下效果渠缕,順便記錄下使用方法。 ...
    space0o0閱讀 2,164評論 0 1
  • 缺少了這個(gè)東西馍忽,我們將永遠(yuǎn)不會(huì)成長。 又到了每天洗澡的時(shí)刻燕差,每天都要將調(diào)節(jié)冷熱旋鈕來回?fù)軇?dòng)幾次,才能找到合適的水溫...
    小墨魚天天很開心閱讀 153評論 0 0