JVM內(nèi)存模型詳解

Java反射機(jī)制

在運(yùn)行狀態(tài)中脓钾,對(duì)于任意一個(gè)類(lèi)售睹,都能夠知道這個(gè)類(lèi)的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象可训,都能夠調(diào)用它的任意方法和屬性昌妹;這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱(chēng)為Java語(yǔ)言的反射機(jī)制捶枢。
簡(jiǎn)而言之:就是把類(lèi)里面的方法變量轉(zhuǎn)化成

public void sayHi(String helloSententce) {
        System.out.println(helloSententce + " " + name);
    }
...
private String throwHello(String tag) {
        return "hello " + tag;
    }

//調(diào)用實(shí)現(xiàn)以上方法
        Class<?> rc = Class.forName("com.czb.Robot");
        System.out.println(rc.getName());
        Robot r = (Robot) rc.getDeclaredConstructor().newInstance();
        Method getHello =rc.getDeclaredMethod("throwHello", String.class);
        getHello.setAccessible(true);
//invoke默認(rèn)返回Object
        Object str = getHello.invoke(r,"Bob");
        System.out.println("getHelloresult is "+str);
        Method sayHi = rc.getMethod("sayHi", String.class);
        Field name = rc.getDeclaredField("name");
        name.setAccessible(true);
        name.set(r,"ALice");
        sayHi.invoke(r,"Welcome");

getDeclaredMethod來(lái)獲取除了繼承或?qū)崿F(xiàn)的的所有方法
getMethod只能獲取public方法,包括繼承或者實(shí)現(xiàn)的方法

ClassLoader的作用

通過(guò)將.class文件的二進(jìn)制數(shù)據(jù)流裝載進(jìn)系統(tǒng)飞崖,然后交給Java虛擬機(jī)進(jìn)行連接烂叔、初始化等操作。
1.BootstrapClassloader:C++編寫(xiě)固歪,加載核心庫(kù)java.*
2.ExtClassLoader:Java編寫(xiě)长已,加載擴(kuò)展庫(kù)javax.*
3.AppClassLoader:Java編寫(xiě),加載程序所在目錄昼牛,加載路徑(classpath)
4.自定義ClassLoader:Java編寫(xiě)
為什么要使用雙親委派機(jī)制去加載類(lèi)
避免多分同樣的字節(jié)碼的加載
例如:System靜態(tài)Class字節(jié)碼术瓮,只需要一份就可以了,第一次加載是在BootstrapClassLoader
隱式加載:new
顯示加載:loadClass贰健,forName
Java9之前newInstentce生成實(shí)例
Java9之后getDeclaredConstructor().newInstance()

▲類(lèi)裝載過(guò)程(比較loadClass和forName)

1.ClassLoader加載.class胞四,生成Class對(duì)象,

加載到內(nèi)存中伶椿,并將這些靜態(tài)數(shù)據(jù)轉(zhuǎn)化成運(yùn)行時(shí)數(shù)據(jù)區(qū)中方法區(qū)的類(lèi)型數(shù)據(jù)辜伟,在運(yùn)行時(shí),數(shù)據(jù)區(qū)堆中生成一個(gè)代表這個(gè)類(lèi)的Java.lang.class對(duì)象作為方法區(qū)類(lèi)數(shù)據(jù)的訪問(wèn)入口

2.鏈接:

校驗(yàn):檢查加載的class的正確性和安全性脊另;
準(zhǔn)備:為類(lèi)變量分配存儲(chǔ)空間并設(shè)置類(lèi)變量初始值导狡,類(lèi)變量(static)隨類(lèi)型信息存放在方法區(qū)中,生命周期很長(zhǎng)偎痛,使用不當(dāng)容易造成內(nèi)存泄漏
解析:JVM將常量池內(nèi)的符號(hào)引用轉(zhuǎn)換為直接引用(不一定非要解析)

3.初始化:執(zhí)行類(lèi)變量賦值和靜態(tài)代碼塊
▲forName初始化完畢旱捧,loadClass只完成加載,還沒(méi)有鏈接

loadClass可以快速加載配置文件踩麦;
如果你要連接Mysql枚赡,driver有一段static代碼段,所以要用forName進(jìn)行加載(因?yàn)殪o態(tài)代碼段是第三步初始化里面完成的)

▲Java內(nèi)存模型(JDK8)

私有內(nèi)存區(qū)域
1.程序計(jì)數(shù)器(線(xiàn)程私有谓谦,不會(huì)內(nèi)存溢出)

當(dāng)前線(xiàn)程所執(zhí)行的字節(jié)碼行號(hào)指示器(邏輯)
通過(guò)改變計(jì)數(shù)器的值來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令(分支贫橙、循環(huán)、跳轉(zhuǎn)反粥、異常處理卢肃、線(xiàn)程恢復(fù))
對(duì)Java方法計(jì)數(shù),如果是Native方法才顿,計(jì)數(shù)器的值為Undefined

2.Java虛擬機(jī)棧(線(xiàn)程私有)

Java方法執(zhí)行的內(nèi)存模型
每個(gè)方法(字節(jié)碼指令)執(zhí)行時(shí)莫湘,都會(huì)創(chuàng)建一個(gè)棧幀(存儲(chǔ):局部變量表、操作數(shù)棧娜膘、動(dòng)態(tài)連接逊脯、返回地址),棧幀持有局部變量和部分結(jié)果以及參與結(jié)果的調(diào)用和返回竣贪,方法調(diào)用結(jié)束時(shí)军洼,棧幀就會(huì)被銷(xiāo)毀
局部變量表:包含了方法執(zhí)行過(guò)程中的所有變量
操作數(shù)棧:在執(zhí)行字節(jié)碼指令過(guò)程中巩螃,類(lèi)似原生CPU寄存器,JVM字節(jié)碼大部分時(shí)間都在操作數(shù)棧的操作上(入棧匕争、出棧避乏、復(fù)制、交換甘桑、產(chǎn)生消費(fèi)變量)拍皮,

3.本地方法棧

native方法

共享內(nèi)存區(qū)域
1.元空間(MetaSpace)和永久代(PermGen)

兩者都是來(lái)存儲(chǔ)class的相關(guān)信息(Methon和Field),
▲‘兩者均是方法區(qū)的實(shí)現(xiàn)跑杭,Java 8之后元空間替代了永久帶
元空間用的是本地內(nèi)存铆帽,永久帶用的是JVM內(nèi)存,也就是說(shuō)本地內(nèi)存多大德谅,理論上元空間就可以有多大爹橱,這樣就直接解決了空間不足的問(wèn)題
●字符串常量池存在永久帶中,容易出現(xiàn)性能問(wèn)題和內(nèi)存溢出
●類(lèi)和方法的信息大小難以確定窄做,給永久帶的大小指定帶來(lái)困難
永久帶會(huì)為GC帶來(lái)不必要的復(fù)雜性愧驱,回收效率偏低
●方便HotSpot與其他JVMJrockit的繼承

Java堆(Heap)

存放對(duì)象實(shí)例
物理內(nèi)存可以不連續(xù)
是GC管理的主要區(qū)域(GC堆,垃圾堆)
●方法區(qū)(No-Heap)存在堆里

JVM 三大性能調(diào)優(yōu)參數(shù)-Xms椭盏, -Xmx组砚, -Xss

-Xms:堆的初始值(不夠會(huì)擴(kuò)容,擴(kuò)容時(shí)會(huì)內(nèi)存抖動(dòng))
-Xmx:堆能到達(dá)的最大值
-Xss:規(guī)定每個(gè)線(xiàn)程虛擬機(jī)棧(及堆棧)的大刑图铡(一般情況256k就可以了糟红,會(huì)影響并發(fā)線(xiàn)程數(shù)的大小)

Java內(nèi)存中堆和棧的區(qū)別

靜態(tài)存儲(chǔ):編譯時(shí)確定每個(gè)數(shù)據(jù)目標(biāo)在運(yùn)行時(shí)的存儲(chǔ)空間需求
棧式存儲(chǔ):數(shù)據(jù)區(qū)需求在編譯的時(shí)候未知蚯舱,運(yùn)行時(shí)進(jìn)入一個(gè)程序模塊前必須知道其大小
堆式存儲(chǔ):編譯時(shí)改化、運(yùn)行時(shí)都不知道所需內(nèi)存大小掩蛤,動(dòng)態(tài)分配
●存儲(chǔ)
堆:創(chuàng)建好的對(duì)象和數(shù)組都會(huì)存到堆里面
棧:基本數(shù)據(jù)類(lèi)型枉昏,引用對(duì)象、數(shù)組時(shí)揍鸟,棧定義變量保存在堆中目標(biāo)的首地址兄裂,局部變量,參數(shù)放在堆棧里面阳藻。
●管理方式
棧自動(dòng)釋放晰奖,堆需要GC
●空間
棧比堆小
●碎片相關(guān)
棧產(chǎn)生的碎片遠(yuǎn)小于小于堆(GC垃圾回收器不是實(shí)時(shí)的)
●分配方式
棧支持靜態(tài)分配和動(dòng)態(tài)分配,而堆只支持動(dòng)態(tài)分配
●效率
棧比堆效率高腥泥,棧不夠靈活

intern函數(shù)到j(luò)dk6+后的改變

如果先前在常量池已經(jīng)創(chuàng)建了匾南,則返回池中該字符串的引用。
(Java 7之后常量池從方法區(qū)(之前還是永久帶)移到了堆里面)

String s1 = new ("asasas")//
s1.intern();
String s2 = "asasas";

"asasas"
否則就看他在不在Java堆里面蛔外,如果有就添加到常量池并返回該引用蛆楞,如果堆里面沒(méi)有溯乒,就在池里創(chuàng)建并返回引用(多了一個(gè)創(chuàng)建)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市豹爹,隨后出現(xiàn)的幾起案子裆悄,更是在濱河造成了極大的恐慌,老刑警劉巖臂聋,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件光稼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡孩等,警方通過(guò)查閱死者的電腦和手機(jī)艾君,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)肄方,“玉大人腻贰,你說(shuō)我怎么就攤上這事“墙眨” “怎么了播演?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)伴奥。 經(jīng)常有香客問(wèn)我写烤,道長(zhǎng),這世上最難降的妖魔是什么拾徙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任洲炊,我火速辦了婚禮,結(jié)果婚禮上尼啡,老公的妹妹穿的比我還像新娘暂衡。我一直安慰自己,他們只是感情好崖瞭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布狂巢。 她就那樣靜靜地躺著,像睡著了一般书聚。 火紅的嫁衣襯著肌膚如雪唧领。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天雌续,我揣著相機(jī)與錄音斩个,去河邊找鬼。 笑死驯杜,一個(gè)胖子當(dāng)著我的面吹牛受啥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼滚局,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼叁温!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起核畴,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤膝但,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后谤草,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體跟束,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年丑孩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冀宴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡温学,死狀恐怖略贮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仗岖,我是刑警寧澤逃延,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站轧拄,受9級(jí)特大地震影響揽祥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜檩电,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一拄丰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧俐末,春花似錦料按、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至丽柿,卻和暖如春恢准,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背甫题。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涂召,地道東北人坠非。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像果正,于是被迫代替她去往敵國(guó)和親炎码。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盟迟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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

  • 1、什么是JVM潦闲? JVM是Java Virtual Machine的縮寫(xiě)攒菠,JVM是一種通用于計(jì)算機(jī)設(shè)備的規(guī)范,它...
    程序員七哥閱讀 506評(píng)論 0 7
  • JVM內(nèi)存模型詳解 1.基本概念 JVM實(shí)際上是運(yùn)行在一個(gè)具體操作系統(tǒng)上的程序進(jìn)程歉闰,對(duì)Java代碼而言辖众,JVM就是...
    1angxi閱讀 578評(píng)論 2 3
  • 程序計(jì)數(shù)器 線(xiàn)程私有,線(xiàn)程執(zhí)行的字節(jié)碼的行號(hào) 虛擬機(jī)棧 線(xiàn)程私有和敬,生命周期與線(xiàn)程相同凹炸。每個(gè)方法執(zhí)行的時(shí)候都會(huì)創(chuàng)建一...
    玄冰0825閱讀 194評(píng)論 0 0
  • 工作之余,想總結(jié)一下JVM相關(guān)知識(shí)昼弟。 Java運(yùn)行時(shí)數(shù)據(jù)區(qū): Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中會(huì)將其管理的...
    Huang遠(yuǎn)閱讀 629評(píng)論 0 2
  • 《深入理解Java虛擬機(jī)》筆記_第一遍 先取看完這本書(shū)(JVM)后必須掌握的部分啤它。 第一部分 走近 Java 從傳...
    xiaogmail閱讀 5,062評(píng)論 1 34