你必須了解的java內(nèi)存管理機(jī)制(一)-運(yùn)行時(shí)數(shù)據(jù)區(qū)

C++與java之間有一堵由內(nèi)存動(dòng)態(tài)分配和垃圾收集技術(shù)所圍成的“高墻”耀怜,墻外的人想進(jìn)去袜茧,墻里的人卻想出來(lái)……

與C爪瓜、C++程序員時(shí)刻要關(guān)注著內(nèi)存的分配與釋放,會(huì)不會(huì)又有哪里出現(xiàn)了內(nèi)存泄露不同是梯捕,java程序員可以“高枕無(wú)憂”厢呵。因?yàn)檫@一切都已經(jīng)有jvm來(lái)幫我們管理了,java程序員只需要關(guān)注具體的業(yè)務(wù)邏輯就可以了科阎,至于內(nèi)存分配與回收述吸,交給jvm去干吧忿族。但這樣也帶來(lái)一個(gè)問(wèn)題锣笨,我們不再去關(guān)注內(nèi)存分配了,不再去關(guān)注內(nèi)存回收了道批。一旦出現(xiàn)內(nèi)存泄露就束手無(wú)策了错英,在不同的應(yīng)用場(chǎng)景,怎么樣去做性能調(diào)優(yōu)就成了一個(gè)問(wèn)題隆豹。所以椭岩,對(duì)于java程序員來(lái)說(shuō),這些是必須了解的一部分璃赡。

沒(méi)有對(duì)象怎么辦判哥?new一個(gè)啊。單身狗程序員每次提到new對(duì)象都激動(dòng)不已碉考,可是你的對(duì)象是怎么new出來(lái)的塌计?new出來(lái)又放在哪里?怎么引用的侯谁?你的對(duì)象被別人動(dòng)了怎么辦锌仅?使用完成之后又是如何釋放的章钾?何時(shí)釋放的?等等等等這些問(wèn)題热芹,如果你不能很輕松的回答出來(lái)贱傀,那么在本系列文章中你可能會(huì)找到一些答案。當(dāng)然伊脓,本人才疏學(xué)淺府寒,文筆拙劣,只是拋磚引玉报腔,理解不周到或者有誤的地方椰棘,歡迎拍磚。

JVM內(nèi)存區(qū)域可以大致劃分為“線程隔離區(qū)域”和“線程共享區(qū)域”榄笙。所謂“線程隔離區(qū)域”即線程非共享區(qū)域邪狞,每個(gè)線程獨(dú)享的,執(zhí)行指令操作機(jī)存放私有數(shù)據(jù)茅撞。不管做什么操作帆卓,不會(huì)影響到其他線程∶浊穑可以想象成剑令,你個(gè)人電腦硬盤中的蒼老師,只能你一個(gè)人在夜深人靜的時(shí)候拉上窗簾獨(dú)自享受拄查,別人無(wú)法同你分享吁津,你刪除或者新下載也不會(huì)對(duì)別人造成影響。而“線程共享區(qū)域”則是所有的線程共同擁有的堕扶,主要存放對(duì)象實(shí)例數(shù)據(jù)碍脏。如果A線程對(duì)這塊區(qū)域的某個(gè)數(shù)據(jù)進(jìn)行了修改,而剛好B線程正在使用或者需要使用該數(shù)據(jù)稍算,則A線程對(duì)數(shù)據(jù)的修改在B線程中也會(huì)得到體現(xiàn)典尾。可以想象成你把蒼老師傳到了某社區(qū)糊探,這時(shí)候網(wǎng)上其他人都能共享你的蒼老師了钾埂。當(dāng)大家看得正興奮的時(shí)候,你突然刪掉了你上傳的老師科平,這時(shí)候大家都只能去尋找新的素材了………褥紫,不知道你是否對(duì)“線程隔離區(qū)域”和“線程共享區(qū)域”的概念有了個(gè)大致了解。在jvm中瞪慧,線程隔離區(qū)域包含程序計(jì)數(shù)器髓考、本地方法棧、虛擬機(jī)棧汞贸。線程共享區(qū)域包含堆區(qū)绳军、永久代(jdk1.8中廢除永久代)印机、直接內(nèi)存(jdk1.8中新增)(看下圖)

一、這是我的私人住所门驾,我不同意射赛,你們別來(lái)!-線程隔離區(qū)域

線程隔離區(qū)域存放什么數(shù)據(jù)呢奶是?局部變量楣责、方法調(diào)用的壓棧操作等。線程隔離區(qū)域包含巴拉巴拉……(看下圖)

1聂沙、睡了一覺(jué)秆麸,剛剛我做到哪了?-程序計(jì)數(shù)器

我們都知道在多線程的場(chǎng)景下及汉,會(huì)發(fā)生線程切換沮趣,如果當(dāng)前執(zhí)行的線程讓出執(zhí)行權(quán),則線程會(huì)被掛起坷随,當(dāng)線程再次被喚醒的時(shí)候房铭,如果沒(méi)有程序計(jì)數(shù)器線程可能就懵逼了,我是誰(shuí)温眉?我在哪缸匪?我要做什么?类溢。但是如果有了程序計(jì)數(shù)器凌蔬,線程就能找到上次執(zhí)行到的字節(jié)碼的位置繼續(xù)往下執(zhí)行。程序計(jì)數(shù)器可以理解為當(dāng)前線程正在執(zhí)行的字節(jié)碼指令的行號(hào)指示器闯冷。分支砂心、循環(huán)、跳轉(zhuǎn)窃躲、異常處理计贰、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個(gè)計(jì)數(shù)器來(lái)完成钦睡。

查閱了一些資料蒂窒,列出了程序計(jì)數(shù)器的三個(gè)特點(diǎn),這里也列舉一下
1)荞怒、如果線程正在執(zhí)行的是Java 方法洒琢,則這個(gè)計(jì)數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令地址

2)、如果正在執(zhí)行的是Native 方法褐桌,則這個(gè)計(jì)數(shù)器值為空(Undefined)衰抑。因?yàn)镹ative方法大多是通過(guò)C實(shí)現(xiàn)并未編譯成需要執(zhí)行的字節(jié)碼指令。那native 方法的多線程是如何實(shí)現(xiàn)的呢荧嵌? native 方法是通過(guò)調(diào)用系統(tǒng)指令來(lái)實(shí)現(xiàn)的呛踊,那系統(tǒng)是如何實(shí)現(xiàn)多線程的則 native 就是如何實(shí)現(xiàn)的砾淌。Java線程總是需要以某種形式映射到OS線程上,映射模型可以是1:1(原生線程模型)谭网、n:1(綠色線程 / 用戶態(tài)線程模型)汪厨、m:n(混合模型)。以HotSpot VM的實(shí)現(xiàn)為例愉择,它目前在大多數(shù)平臺(tái)上都使用1:1模型劫乱,也就是每個(gè)Java線程都直接映射到一個(gè)OS線程上執(zhí)行宫静。此時(shí)侮叮,native方法就由原生平臺(tái)直接執(zhí)行驹饺,并不需要理會(huì)抽象的JVM層面上的“pc寄存器”概念——原生的CPU上真正的PC寄存器是怎樣就是怎樣邓梅。就像一個(gè)用C或C++寫的多線程程序弄唧,它在線程切換的時(shí)候是怎樣的退盯,Java的native方法也就是怎樣的狱从。

3)改橘、此內(nèi)存區(qū)域是唯一一個(gè)在Java虛擬機(jī)規(guī)范中沒(méi)有規(guī)定任何OutOfMemoryError情況的區(qū)域(程序運(yùn)行過(guò)程中計(jì)數(shù)器中改變的只是值破花,而不會(huì)隨著程序的運(yùn)行需要更大的空間)

2拉一、自己的事情自己做!-虛擬機(jī)棧

這個(gè)區(qū)域就是我們經(jīng)常所說(shuō)的棧旧乞,是java方法執(zhí)行的內(nèi)存模型蔚润,也是我們?cè)陂_(kāi)發(fā)中接觸得很多的一塊區(qū)域。虛擬機(jī)棧存放當(dāng)前正在執(zhí)行方法的時(shí)候所需要的數(shù)據(jù)尺栖、地址嫡纠、指令。每個(gè)線程都會(huì)獨(dú)享一塊椦佣模空間除盏,每次方法調(diào)用都會(huì)創(chuàng)建一個(gè)棧幀,棧幀保存了方法的局部局部變量挫以、操作數(shù)棧者蠕、動(dòng)態(tài)鏈接、出口等信息掐松。棧幀的深度也是有限制的踱侣,超過(guò)限制會(huì)拋出StackOverflowError異常。

我們結(jié)合一個(gè)例子來(lái)了解一下虛擬機(jī)棧和棧幀大磺,我們有如下代碼:

public class myProgram {
    public static void main(String[] args) {
        String str = "my String";
        methodOne(1);
    }
    public static void methodOne(int i) {
        int j = 2;
        int sum = i + j;
        // ......
        methodTwo();
        // .....
    }
    public static void methodTwo() {
        if (true) {
            int j = 0;
        }
        if (true) {
            int k = 1;
        }
        return;
    }
}

代碼很簡(jiǎn)單抡句,main調(diào)用methodOne,methodOne調(diào)用methodTwo杠愧,如果當(dāng)前正在執(zhí)行methodTwo方法待榔,則虛擬機(jī)棧中棧幀的情況應(yīng)該是如下圖情況,棧頂為正在執(zhí)行的方法流济。

我們能看到锐锣,每個(gè)棧幀都包含局部變量表腌闯,操作數(shù)棧、動(dòng)態(tài)鏈接雕憔、返回地址等……

1)绑嘹、局部變量表
顧名思義,局部變量表就是存放局部變量的表橘茉,局部變量包括方法形參工腋、方法內(nèi)部定義的局部變量。局部變量表由多個(gè)變量槽(slot)組成畅卓,每個(gè)槽位都有個(gè)索引號(hào)擅腰,索引的范圍是從0開(kāi)始至局部變量最大的slot空間,虛擬機(jī)就是通過(guò)索引定位的方式使用局部變量表翁潘。比如在methodOne方法中趁冈,形參i就是在0號(hào)索引的slot中,局部變量j就放在1號(hào)索引的slot中拜马,我們看看結(jié)合methodOne方法的字節(jié)碼進(jìn)行分析(通過(guò)javap -verbose myProgram查看字節(jié)碼文件)渗勘。

public static void methodOne(int);
descriptor: (I)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: iconst_2
         1: istore_1
         2: iload_0
         3: iload_1
         4: iadd
         5: istore_2
         6: invokestatic  #4                  // Method methodTwo:()V
9: return
      LineNumberTable:
        line 8: 0
        line 9: 2
        line 12: 6
        line 14: 9

0:加載int類型常量2
1:存儲(chǔ)到索引為1的變量中(這里指源程序中的j)
2:加載索引為0的變量(這里指源程序中的i)
3:加載索引為1的變量(這里指源程序中的j)
4:執(zhí)行add指令
5:將執(zhí)行結(jié)果存儲(chǔ)到索引為2的變量中(這里指源程序中的sum)
6:靜態(tài)調(diào)用

需要注意的一點(diǎn)是,為了盡可能節(jié)省棧幀的空間俩莽,局部變量表中的slot是可以重用的旺坠,方法體重定義的變量,其作用域不一定會(huì)覆蓋整個(gè)方法體扮超,我們看看methodTwo的源碼取刃,第一個(gè)if和第二個(gè)if的作用域不一樣,所以內(nèi)部變量可能是用的同一個(gè)slot出刷,我們可以通過(guò)methodTwo方法的字節(jié)碼來(lái)驗(yàn)證一下

public static void methodTwo();
descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=1, args_size=0
         0: iconst_0
         1: istore_0
         2: iconst_1
         3: istore_0
         4: return
      LineNumberTable:
        line 19: 0
        line 23: 2
        line 26: 4

你看璧疗,我沒(méi)騙你吧,methodTwo方法兩個(gè)if中的變量j和k馁龟,使用的都是索引為0的slot崩侠。這樣的設(shè)計(jì)可以節(jié)省棧幀的空間,同時(shí)也會(huì)影響jvm的垃圾回收坷檩,因?yàn)榫植孔兞勘硎荊C Root的一部分却音,局部變量表slot中當(dāng)前存放的變量關(guān)聯(lián)的對(duì)象為可達(dá)對(duì)象(后面講到垃圾回收時(shí)候再詳細(xì)講)。

2)淌喻、操作數(shù)棧
操作數(shù)棧也是一個(gè)棧僧家,也看可以成為表達(dá)式棧。操作數(shù)棧和局部變量表在訪問(wèn)方式上有著較大的差異裸删,它不是通過(guò)索引來(lái)訪問(wèn),而是通過(guò)標(biāo)準(zhǔn)的棧操作—壓棧和出椪笤—來(lái)訪問(wèn)的涯塔。我們對(duì)變量的操作都是在操作數(shù)棧中完成的肌稻,我們依然拿methodOne方法來(lái)舉例。再看一下methodOne方法的字節(jié)碼:

public static void methodOne(int);
descriptor: (I)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: iconst_2
         1: istore_1
         2: iload_0
         3: iload_1
         4: iadd
         5: istore_2
         6: invokestatic  #4                  // Method methodTwo:()V
9: return
      LineNumberTable:
        line 8: 0
        line 9: 2
        line 12: 6
        line 14: 9

下圖為每一行字節(jié)碼對(duì)應(yīng)操作數(shù)棧和本地變量表之間的關(guān)系匕荸,具體看圖爹谭,不用多做描述了。


i

3)榛搔、動(dòng)態(tài)鏈接
每個(gè)棧幀都包含一個(gè)指向運(yùn)行時(shí)常量池中該棧幀所屬方法的引用诺凡,持有這個(gè)引用是為了支持方法調(diào)用過(guò)程中的動(dòng)態(tài)連接。剛開(kāi)始看這一段的時(shí)候總是覺(jué)得很生澀践惑,比較拗口腹泌。我們還是繼續(xù)看那段代碼的字節(jié)碼文件,其中有一段叫做“Constant pool”尔觉,里面存儲(chǔ)了該Class文件里的大部分常量的內(nèi)容(包括類和接口的全限定名凉袱、字段的名稱和描述符以及方法的名稱和描述符)。

不知道你有沒(méi)有注意我們字節(jié)碼中是怎么處理menthodOne方法的調(diào)用的侦铜?在main方法中調(diào)用methodone方法的字節(jié)碼為invokestatic #3专甩,這里的#3就是一個(gè)” 符號(hào)引用”,我們發(fā)現(xiàn)#3還引用著另外的常量池項(xiàng)目钉稍,順著這條線把能傳遞到的常量池項(xiàng)都找出來(lái)(標(biāo)記為Utf8的常量池項(xiàng))涤躲。由此我們可以看出,invokestatic 指令就是以常量池中指向方法的符號(hào)引用作為參數(shù)贡未,完成方法的調(diào)用篓叶。這些符號(hào)引用一部分在類的加載階段(解析)或第一次使用的時(shí)候就轉(zhuǎn)化為了直接引用(指向數(shù)據(jù)所存地址的指針或句柄等),這種轉(zhuǎn)化稱為靜態(tài)鏈接羞秤。而相反的缸托,另一部分在運(yùn)行期間轉(zhuǎn)化為直接引用,就稱為動(dòng)態(tài)鏈接瘾蛋。我們看一下字節(jié)碼中的常量池和符號(hào)引用俐镐,注意main方法中的#2 #3:

Constant pool:
   #1 = Methodref          #6.#18         // java/lang/Object."<init>":()V
#2 = String             #19            // my String
#3 = Methodref          #5.#20         // myProgram.methodOne:(I)V
#4 = Methodref          #5.#21         // myProgram.methodTwo:()V
#5 = Class              #22            // myProgram
#6 = Class              #23            // java/lang/Object
#7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               main
  #12 = Utf8               ([Ljava/lang/String;
)V
  #13 = Utf8               methodOne
  #14 = Utf8               (I)V
  #15 = Utf8               methodTwo
  #16 = Utf8               SourceFile
  #17 = Utf8               myProgram.java
  #18 = NameAndType        #7:#8          // "<init>":()V
#19 = Utf8               my String
  #20 = NameAndType        #13:#14        // methodOne:(I)V
#21 = NameAndType        #15:#8         // methodTwo:()V
#22 = Utf8               myProgram
  #23 = Utf8               java/lang/Object
  public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;
)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=2, args_size=1
         0: ldc           #2                  // String my String
2: astore_1
         3: iconst_1
         4: invokestatic  #3                  // Method methodOne:(I)V
7: return
      LineNumberTable:
        line 3: 0
        line 4: 3
        line 5: 7

4)、返回地址
我們的經(jīng)常使用return x;來(lái)使方法返回一個(gè)值給方法調(diào)用者哺哼,如果沒(méi)有返回值的方法也可以在方法的方法需要返回的地方加上return;當(dāng)然佩抹,這不是必須的,因?yàn)樵创a在轉(zhuǎn)化為字節(jié)碼的時(shí)候取董,總是會(huì)在方法的最后加上return指令棍苹,不信你看上面methodTwo方法的字節(jié)碼那張圖片。

正常情況下茵汰,方法遇到返回指令退出枢里,這種退出方法的方式稱為正常完成出口。如果方法正常返回,則當(dāng)前棧幀從java棧中彈出栏豺,恢復(fù)發(fā)起調(diào)用者的方法的棧幀彬碱,如果方法有返回值,jvm會(huì)把返回值壓入到發(fā)起調(diào)用方法的操作數(shù)棧奥洼。但是在異常情況下巷疼,方法執(zhí)行遇到了異常,且這個(gè)異常在方法體內(nèi)未得到處理灵奖,方法則會(huì)異常退出嚼沿,這種退出方式稱為異常完成出口。當(dāng)異常拋出且沒(méi)有被捕捉時(shí)瓷患,則方法立即終止骡尽,然后JVM恢復(fù)發(fā)起調(diào)用的方法的棧幀,如果在調(diào)用者中也未對(duì)異常進(jìn)行捕捉尉尾,則調(diào)用者也會(huì)立即終止爆阶,層層向上,直到最外層拋出異常沙咏。

3辨图、樓上做不了的事情,來(lái)我這做肢藐!-本地方法棧

本地方法是什么故河?本地方法就是在jdk中(也可以自定義)那些被Native關(guān)鍵字修飾的方法(下圖)。這類方法有點(diǎn)類似java中的接口吆豹,沒(méi)有實(shí)現(xiàn)體鱼的,但實(shí)際上是由jvm在加載時(shí)調(diào)用底層實(shí)現(xiàn)的,實(shí)現(xiàn)體是由非java語(yǔ)言(如C痘煤、C++)實(shí)現(xiàn)的凑阶,所以本地方法可以理解為連接java代碼和其他語(yǔ)言實(shí)現(xiàn)的代碼的入口。而本地方法棧的功能就類似于虛擬機(jī)棧衷快,只是一個(gè)服務(wù)于java方法執(zhí)行宙橱,一個(gè)服務(wù)于執(zhí)行本地方法執(zhí)行。

二蘸拔、來(lái)啊师郑,快活啊调窍!反正有大把空間宝冕!-線程共享區(qū)域

1、 喂邓萨,你的對(duì)象都在這里地梨!-堆

堆區(qū)域在jvm中是非常重要的一塊區(qū)域菊卷,因?yàn)槲覀兤匠?chuàng)建的對(duì)象的實(shí)例就存在在這個(gè)區(qū)域,這個(gè)區(qū)域的幾乎是被所有線程共享湿刽。同時(shí)也是java虛擬機(jī)管理的內(nèi)存中最大的一塊的烁。由于目前主流的垃圾收集器都采用分代收集算法褐耳,所以通常將堆細(xì)分為新生代诈闺、老年代,新生代又分為兩塊Eden區(qū)铃芦、From Survivor區(qū)雅镊、To Survivor區(qū)(這里主要針對(duì)通常使用的分代收集器,G1收集器采用不同的劃分策略刃滓,后面有機(jī)會(huì)再講)仁烹。不過(guò)不管怎么劃分,目的都是為了更合理的利用內(nèi)存咧虎,提高內(nèi)存空間使用率卓缰,提高垃圾回收的效率和回收質(zhì)量。下圖展示了堆區(qū)域的劃分


我們?cè)谶@篇文章里只談堆區(qū)內(nèi)存的劃分砰诵,關(guān)于內(nèi)存分配征唬、內(nèi)存回收等會(huì)在下篇文章細(xì)講,因?yàn)樯婕暗膬?nèi)容太多了……不過(guò)我們可以先思考幾個(gè)問(wèn)題1茁彭、為什么需要區(qū)分新生代总寒、老年代?2理肺、為什么將新生代分為Eden摄闸、Survivor區(qū)?各區(qū)大小怎么分配妹萨?有什么分配依據(jù)年枕?

2、 治不了你乎完?那我就廢了你熏兄!-方法區(qū)

看標(biāo)題可能會(huì)有些誤解,其實(shí)這里廢除的是永久代的概念囱怕,而不是方法區(qū)霍弹。剛開(kāi)始總是搞不清這兩者的關(guān)系,后來(lái)就去查閱了一些資料總算是搞清楚了一些娃弓,書(shū)上是這么說(shuō)的:“JVM的虛擬機(jī)規(guī)范只是規(guī)定了有方法區(qū)這么個(gè)概念和它的作用典格,并沒(méi)有規(guī)定如何去實(shí)現(xiàn)它。不同JVM的方法區(qū)的實(shí)現(xiàn)會(huì)不一樣台丛,比如在HotSpot中使用永久代實(shí)現(xiàn)方法區(qū)耍缴,其他JVM并沒(méi)有永久代的概念砾肺。方法區(qū)是一種規(guī)范,永久代是一種實(shí)現(xiàn)防嗡”渫簦”

所以,我們常說(shuō)的新生代蚁趁、老年代裙盾、永久代中的永久代就是方法區(qū)的一種實(shí)現(xiàn),且只存在于HotSpot虛擬機(jī)中有這種概念他嫡。用過(guò)jdk1.8之前的版本(HotSpot虛擬機(jī))的同學(xué)應(yīng)該經(jīng)常能碰到永久代溢出的異撤伲“java.lang.OutOfMemoryError: PermGen space”,這里的PermGen space指的是永久代钢属。在jdk6中徘熔,永久代包含方法區(qū)和常量池,但是在jdk1.7的版本中規(guī)劃去除永久代淆党,于是在1.7中將常量池移到了老年代中酷师。在jdk1.8中徹底廢除了永久代,取而代之的是元空間染乌。

3山孔、 會(huì)有天使替我去愛(ài)你!-直接內(nèi)存

永久代設(shè)置太大吧慕匠,浪費(fèi)資源饱须!永久代設(shè)置太小吧,溢出了台谊!于是讓人惱火的永久代溢出的異常時(shí)常發(fā)生蓉媳,并且永久代的GC效率低下,于是锅铅,在jdk1.8中徹底廢除了永久區(qū)酪呻,放到了直接內(nèi)存的元空間中!元空間的本質(zhì)和永久代類似盐须,都是對(duì)JVM規(guī)范中方法區(qū)的實(shí)現(xiàn)玩荠。元空間相比永久代有什特性呢?永久代在物理上是堆的一部分贼邓,與新生代老年代的地址是連續(xù)的阶冈,而元空間屬于本地內(nèi)存,不受JVM控制塑径,也不會(huì)發(fā)生永久代溢出的異常女坑。

直接內(nèi)存也可以稱為堆外內(nèi)存,為什么要將方法區(qū)放入到直接內(nèi)存呢统舀?
1匆骗、 永久代會(huì)為 GC 帶來(lái)不必要的復(fù)雜度劳景,并且回收效率偏低。
2碉就、 類及方法的信息等比較難確定其大小盟广,因此永久代調(diào)優(yōu)較為困難,容易發(fā)生內(nèi)存溢出瓮钥。
3筋量、 加快了復(fù)制的速度。因?yàn)槎褍?nèi)在flush到遠(yuǎn)程時(shí)骏庸,會(huì)先復(fù)制到直接內(nèi)存(非堆內(nèi)存)毛甲,然后再發(fā)送年叮,而堆外內(nèi)存相當(dāng)于省略掉了這個(gè)工作具被。
4、 Oracle 可能會(huì)將HotSpot 與 JRockit 合二為一

結(jié)尾

終于迎來(lái)了這篇文章的“殺青”只损!剛開(kāi)始搭建站點(diǎn)的時(shí)候的計(jì)劃是做到站點(diǎn)周更一姿,但是僅僅這篇文章,前前后后就花了一個(gè)多月(當(dāng)然跃惫,也只是有空的時(shí)候才來(lái)寫寫)叮叹!才發(fā)現(xiàn)要寫一篇技術(shù)文章還是真的要花很多功夫的,既要引經(jīng)還要據(jù)典爆存!后續(xù)會(huì)持續(xù)記錄蛉顽、分享!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末先较,一起剝皮案震驚了整個(gè)濱河市携冤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闲勺,老刑警劉巖曾棕,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異菜循,居然都是意外死亡翘地,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門癌幕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)衙耕,“玉大人,你說(shuō)我怎么就攤上這事勺远〕却” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵谚中,是天一觀的道長(zhǎng)渴杆。 經(jīng)常有香客問(wèn)我寥枝,道長(zhǎng),這世上最難降的妖魔是什么磁奖? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任囊拜,我火速辦了婚禮,結(jié)果婚禮上比搭,老公的妹妹穿的比我還像新娘冠跷。我一直安慰自己,他們只是感情好身诺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布蜜托。 她就那樣靜靜地躺著,像睡著了一般霉赡。 火紅的嫁衣襯著肌膚如雪橄务。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,604評(píng)論 1 305
  • 那天穴亏,我揣著相機(jī)與錄音蜂挪,去河邊找鬼。 笑死嗓化,一個(gè)胖子當(dāng)著我的面吹牛棠涮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刺覆,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼严肪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了谦屑?” 一聲冷哼從身側(cè)響起驳糯,我...
    開(kāi)封第一講書(shū)人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎伦仍,沒(méi)想到半個(gè)月后结窘,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡充蓝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年隧枫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谓苟。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡官脓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涝焙,到底是詐尸還是另有隱情卑笨,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布仑撞,位于F島的核電站赤兴,受9級(jí)特大地震影響妖滔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桶良,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一座舍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陨帆,春花似錦曲秉、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至纲爸,卻和暖如春亥鸠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缩焦。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工读虏, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人袁滥。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像灾螃,于是被迫代替她去往敵國(guó)和親题翻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

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