国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

深入理解jvm運(yùn)行時(shí)區(qū)域

ChanceWong / 1935人閱讀

摘要:內(nèi)存區(qū)域虛擬機(jī)在運(yùn)行程序時(shí),會將其管理的內(nèi)存區(qū)域劃分成若干個(gè)不同的數(shù)據(jù)區(qū)域。運(yùn)行時(shí)常量池運(yùn)行時(shí)常量池是方法區(qū)的一部分。另外一部分官方稱為用于存儲自身運(yùn)行時(shí)的數(shù)據(jù),比如哈希值年齡鎖狀態(tài)標(biāo)志偏向線程等。

前言

最近一直在看周志明老師的《深入理解虛擬機(jī)》,總是看了忘,忘了又看,陷入這樣無休止的循環(huán)當(dāng)中。抱著紙上得來終覺淺的想法,準(zhǔn)備陸續(xù)的寫幾篇學(xué)習(xí)筆記,梳理知識的脈絡(luò)并強(qiáng)化一下對知識的掌握。(本文遠(yuǎn)遠(yuǎn)談不上深入,但為了博瀏覽量,請?jiān)徫疫@個(gè)標(biāo)題黨)。

概述

"Write Once,Run Anywhere"是sun公司用來展示java語言跨平臺特性的口號。這標(biāo)示著java語言可以在任何機(jī)器上開發(fā),并編譯成標(biāo)準(zhǔn)的字節(jié)碼,在任何具有jvm虛擬機(jī)上的設(shè)備運(yùn)行,這也是java語言早期興起的關(guān)鍵。java另一大特性是其虛擬機(jī)的內(nèi)存自動管理機(jī)制,這使得java程序員在創(chuàng)建任何一個(gè)對象時(shí)都不需要去寫與之配對的delete/free代碼(釋放內(nèi)存),不容易出現(xiàn)因?yàn)榇中拇笠舛鴮?dǎo)致的內(nèi)存泄漏和內(nèi)存溢出的問題??墒且?yàn)閷?nèi)存管理的權(quán)利交給虛擬機(jī),一旦出現(xiàn)內(nèi)存泄漏和內(nèi)存溢出的問題,如果我們不了解虛擬機(jī)相關(guān)的知識,排查問題將是一件極為艱難的事情。

java內(nèi)存區(qū)域

java虛擬機(jī)在運(yùn)行java程序時(shí),會將其管理的內(nèi)存區(qū)域劃分成若干個(gè)不同的數(shù)據(jù)區(qū)域。接下來的知識如果沒有指明jdk版本號,統(tǒng)一以jdk1.6為標(biāo)準(zhǔn),內(nèi)存區(qū)域如下圖所示:

程序計(jì)數(shù)器
程序計(jì)數(shù)器是一塊較小的內(nèi)存區(qū)域,可以把它看成是當(dāng)前線程執(zhí)行字節(jié)碼的行號指示器。由于java虛擬機(jī)的多線程是通過線程輪流切換并分配處理器執(zhí)行時(shí)間的方式實(shí)現(xiàn)的。在任意一個(gè)確定的時(shí)刻,一個(gè)cpu核心只會執(zhí)行一個(gè)線程,因此為了cpu在切換線程后可以找到上次運(yùn)行的位置,每條線程都應(yīng)該有一個(gè)獨(dú)立的程序計(jì)數(shù)器。各個(gè)線程間的程序計(jì)數(shù)器應(yīng)互不影響并獨(dú)立存儲。如果此時(shí)運(yùn)行的是java方法,這個(gè)記錄器記錄的是正在執(zhí)行虛擬機(jī)字節(jié)碼指令的地址,如果執(zhí)行的是native方法,則這個(gè)計(jì)數(shù)器為空。此內(nèi)存區(qū)域也是唯一一個(gè)java虛擬機(jī)規(guī)范里沒有規(guī)定任何OutOfMemoryError情況的區(qū)域。

java虛擬機(jī)棧
虛擬機(jī)棧也是線程私有的,它的生命周期和線程是相同的,它描述的就是java方法執(zhí)行的內(nèi)存區(qū)域。每個(gè)方法在執(zhí)行的同時(shí)都會創(chuàng)建一個(gè)棧幀用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。每一個(gè)方法從調(diào)用到執(zhí)行完成就對應(yīng)著一個(gè)棧幀在虛擬機(jī)中從入棧到出棧的過程。如果線程請求的深入大于棧所允許的深度,就會拋出StackOverflowError異常,大部分虛擬機(jī)支持動態(tài)擴(kuò)展,如果擴(kuò)展時(shí)無法申請到足夠的內(nèi)存,則會拋出OutOfMemoryError異常.
局部變量表:存放了編譯器可知的各種基本數(shù)據(jù)類型(8種基礎(chǔ)類型)、對象的引用(reference類型)和returnAddress類型(指向了一條字節(jié)碼指令的地址),局部變量表在編譯期是就可確定其大小。
操作數(shù)棧:也是棧的一種,虛擬機(jī)把操作數(shù)棧作為它的工作區(qū),大多數(shù)指令都要從這里彈出數(shù)據(jù),執(zhí)行運(yùn)算,然后把結(jié)果壓回操作數(shù)棧。
動態(tài)鏈接: Class 文件中存放了大量的符號引用,字節(jié)碼中的方法調(diào)用指令就是以常量池中指向方法的符號引用作為參數(shù)。這些符號引用一部分會在類加載階段或第一次使用時(shí)轉(zhuǎn)化為直接引用,這種轉(zhuǎn)化稱為靜態(tài)解析。另一部分將在每一次運(yùn)行期間轉(zhuǎn)化為直接引用,這部分稱為動態(tài)連接.可以簡單的理解為為了支持在方法中使用靜態(tài)變量和常量...
方法出口:一般來說只有兩種方法出口。一種是正常執(zhí)行完畢,可以講程序計(jì)數(shù)器作為返回地址返回,另外一種就是拋出異常,此時(shí)返回地址為空,需要異常處理器來確定返回地址。

本地方法棧
本地方法棧和虛擬機(jī)棧的作用是非常相似的。他們之間的區(qū)別不過就是一個(gè)為java方法服務(wù),另外一個(gè)為native方法使用。本地方法棧的實(shí)現(xiàn)由java虛擬機(jī)規(guī)范所定義,各大虛擬機(jī)廠商在虛擬機(jī)規(guī)范的基礎(chǔ)上自由實(shí)現(xiàn).

java堆
java堆是所有線程共享的內(nèi)存區(qū)域,也是大多數(shù)應(yīng)用中虛擬機(jī)管理內(nèi)存區(qū)域最大的一塊,在虛擬機(jī)啟動時(shí)創(chuàng)建。其作用就是為了存放對象實(shí)例。從內(nèi)存回收的角度看,現(xiàn)在的收集器基本都采用分代收集算法。所以java堆還可以分為新生代和老年代。其中新生代又可分為Eden空間、From Survivor空間、To Survivor空間。堆內(nèi)存區(qū)域的大小是通過-Xmx和-Xms來控制。如果在堆中沒有完成內(nèi)存實(shí)例分配,并且堆也無法擴(kuò)展,將會拋出OutOfMemoryError異常。

方法區(qū)
方法區(qū)也是所有線程共享的內(nèi)存區(qū)域,它用于存儲已經(jīng)被虛擬機(jī)加載的類信息、常量、靜態(tài)變量等數(shù)據(jù)。它有一個(gè)別名叫做Non-heap(非堆),目的就是為了和堆做區(qū)分。對于經(jīng)常在hotspot虛擬機(jī)上的開發(fā)者來說,更愿意將方法區(qū)成為永久代,本質(zhì)上兩者并不等價(jià)。只不過jvm設(shè)計(jì)團(tuán)隊(duì)選擇把gc分代收集擴(kuò)展至方法區(qū),或者說使用永久代來實(shí)現(xiàn)方法區(qū)。但就目前發(fā)展來看,這樣并不是一個(gè)好做法。jdk1.7中已經(jīng)將原本放在永久代的字符串常量池移出,jdk1.8已經(jīng)完全廢除永久代這個(gè)概念,改用metaspace(元空間)。這塊區(qū)域的回收主要針對常量池的回收和對類型的卸載,條件相當(dāng)?shù)目量蹋话慊厥粘煽円埠茈y讓人滿意,但對其回收是非常有必要的。Sun公司的bug列表中,曾經(jīng)出現(xiàn)多個(gè)嚴(yán)重的bug就是因?yàn)榈桶姹镜奶摂M機(jī)未對方法區(qū)進(jìn)行回收。當(dāng)方法區(qū)無法滿足內(nèi)存分配需求時(shí),將拋出OutOfMemoryError異常。

運(yùn)行時(shí)常量池
運(yùn)行時(shí)常量池是方法區(qū)的一部分。Class文件除了有類的版本、字段、方法、接口等描述信息等,還有一項(xiàng)信息是常量池,常量池在經(jīng)過類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池中存放。運(yùn)行時(shí)常量池的一個(gè)重要特征就是具備動態(tài)性,java語言允許在運(yùn)行期加新的常量放入池中。運(yùn)行時(shí)常量池是方法去的一部分,自然會受到方法區(qū)內(nèi)存的限制,當(dāng)無法申請到內(nèi)存時(shí)將會拋出OutOfMemory異常。

直接內(nèi)存
直接內(nèi)存并不是jvm內(nèi)存管理區(qū)域的一部分,但也被頻繁的使用,并可能導(dǎo)致OOM一場出現(xiàn)。在jdk1.4之后新加入了nio(new Input/Output)類,引入了一種基于通道(channel)和緩沖區(qū)(Buffer)的I/O方式,它使用native函數(shù)分配堆外內(nèi)存。它不會說到j(luò)ava堆大小的限制,但是會受到本機(jī)總內(nèi)存的限制。在配置虛擬機(jī)參數(shù)時(shí),經(jīng)常會忽略直接內(nèi)存,從而導(dǎo)致動態(tài)擴(kuò)展時(shí)出現(xiàn)OOM異常。

hotspot虛擬機(jī)對象探秘

對象的創(chuàng)建
在java語言層面,對象的創(chuàng)建通過new關(guān)鍵字來就可以實(shí)現(xiàn)。在jvm層面,對象(僅限于普通對象,不包括數(shù)組和class對象)的創(chuàng)建又是什么樣子的呢?
當(dāng)虛擬機(jī)接收到一條new指令時(shí),會先跟據(jù)new指令的參數(shù)去常量池查詢這個(gè)類的符號引用,并檢查這個(gè)類是否已經(jīng)被虛擬機(jī)加載、解析、初始化。如果沒有,則要先執(zhí)行相應(yīng)的類加載過程。接下來要為對象分配內(nèi)存,假設(shè)堆內(nèi)存是絕對規(guī)整的,只需要一個(gè)指針作為臨界點(diǎn)來標(biāo)記內(nèi)存已使用和內(nèi)存未使用的區(qū)域,每次分配對象只需要移動與對象大小相等的距離即可,這種內(nèi)存分配方式叫做"指針碰撞"。如果堆內(nèi)存不是絕對規(guī)整的,我們無法通過簡單的指針碰撞去分配內(nèi)存,這時(shí)就需要虛擬機(jī)去維護(hù)一個(gè)列表,記錄哪些內(nèi)存區(qū)域是未使用的和其內(nèi)存區(qū)域的大小,給對象分配內(nèi)存只需要去空閑列表里找到一個(gè)塊足夠大的內(nèi)存劃分給對象實(shí)例即可,這種方式叫做“空閑列表”。
在一個(gè)應(yīng)用程序中,創(chuàng)建對象是非常頻繁的行為,僅僅是一個(gè)指針的分配在并發(fā)情況下都不是絕對安全的。很有可能正在給A對象分配內(nèi)存,指針還沒來得及修改位置,又發(fā)生著使用原來的指針給B對象分配內(nèi)存。jvm提供了兩種解決方案,1.jvm使用cas配上失敗重試來保證指針更新操作的原子性。2.將內(nèi)存分配的動作按照線程分區(qū)域進(jìn)行,也就是預(yù)先給每個(gè)線程申請一部分區(qū)域,這種方式稱為本地緩沖(Thread Local Allocate Buffer,TLAB).哪個(gè)線程要分配對象就在哪個(gè)線程的tlab上分配。只有當(dāng)tlab用完并分配新的tlab才需要同步鎖定,虛擬機(jī)是否開啟tlab可以通過參數(shù)-XX:+/UseTLAB來決定。
內(nèi)存分配好后,jvm需要分配的內(nèi)存都初始化為零值(不包括對象頭),以便java代碼中變量不賦值,也可以訪問到其數(shù)據(jù)類型對應(yīng)的零值。接下來需要對對象頭部分來做一個(gè)設(shè)置,對象頭中主要包括類的元信息,對象的哈希碼,對象的gc分代年齡以及鎖記錄等,在上面這些工作都完成時(shí),從虛擬機(jī)的角度來說一個(gè)對象就已經(jīng)創(chuàng)建好了。但從java語言的角度來看,還需要其執(zhí)行構(gòu)造方法讓其按照程序員的意愿去構(gòu)造這個(gè)對象,這樣一個(gè)真正可用的對象才算完全產(chǎn)生出來。

對象的內(nèi)存布局
對象的主要分為三部分對象頭(Object Header),實(shí)例數(shù)據(jù)(Instance Data)和對齊填充(Padding).
對象頭主要分為兩部分,一部分是類型指針,通過類型指針指向類的元數(shù)據(jù)(確定對象是哪個(gè)類的實(shí)例)。另外一部分官方稱為"Mark Word",用于存儲自身運(yùn)行時(shí)的數(shù)據(jù),比如哈希值、gc年齡、鎖狀態(tài)標(biāo)志、偏向線程id等。“Mark word”的存儲內(nèi)容如下圖所示:

實(shí)例數(shù)據(jù)存儲的是真正有效的數(shù)據(jù),也是我們業(yè)務(wù)所關(guān)心的數(shù)據(jù)。
對齊填充并不是必須存在的,只是因?yàn)閔otspot要求對象的大小必須是8bit的整數(shù)倍,而"Mark Word"又一定是8的整數(shù)倍,實(shí)例數(shù)據(jù)大小不確定,所以用對齊填充來補(bǔ)充其空余的地方。

對象的訪問定位
創(chuàng)建對象是為了訪問對象。我們在需要通過java虛擬機(jī)棧的reference引用去獲取堆上的具體對象。但是并沒有規(guī)定如何通過一個(gè)引用具體的定位訪問到一個(gè)對象,所以對想得訪問方式也是由虛擬機(jī)的實(shí)現(xiàn)定義的。主流的實(shí)現(xiàn)方式有使用句柄和直接指針兩種。如下圖所示:

使用句柄池其最大的好處就是保證reference引用中句柄的穩(wěn)定,reference引用存放的是句柄池的地址,句柄中保存了指向?qū)ο髮?shí)例數(shù)據(jù)和對象類型數(shù)據(jù)的指針,在虛擬機(jī)gc的時(shí)候,對象會發(fā)生非常頻繁的移動,這個(gè)時(shí)候只要修改句柄指向?qū)ο髷?shù)據(jù)的指針即可,不需要修改reference.
使用直接指針的好處就是塊,可以減少一次指針定位。由于訪問對象在一個(gè)程序中將是非常頻繁的操作,積少成多,所以這也是一個(gè)非??捎^的優(yōu)化。

OOM異常--例子分析

經(jīng)過一長串的的理論分析,我們已經(jīng)大致清楚java的內(nèi)存區(qū)域,現(xiàn)在我們使用具體的例子來驗(yàn)證。會將jvm的參數(shù)放在代碼注釋中。

java堆溢出

/**
 * -XX:+PrintGCDetails -Xmx20m -Xms20m
 */
public class HeapOOM {

    static class OOMObjectt {
    }

    public static void main(String[] args) {

        List list = new ArrayList();
        try {
            while (true){
                list.add(new OOMObjectt());
            }
        } catch (Exception e) {

        }
    }
}

其運(yùn)行結(jié)果如下:

[GC [PSYoungGen: 5898K->480K(6656K)] 5898K->3769K(20480K), 0.0043241 secs] [Times: user=0.09 sys=0.00, real=0.00 secs] 
[GC [PSYoungGen: 6315K->488K(6656K)] 9604K->8320K(20480K), 0.0064706 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC [PSYoungGen: 6632K->0K(6656K)] [ParOldGen: 10997K->13393K(13824K)] 17629K->13393K(20480K) [PSPermGen: 3164K->3163K(21504K)], 0.1786099 secs] [Times: user=0.58 sys=0.00, real=0.18 secs] 
[Full GC [PSYoungGen: 3031K->3001K(6656K)] [ParOldGen: 13393K->13393K(13824K)] 16425K->16394K(20480K) [PSPermGen: 3163K->3163K(21504K)], 0.1063835 secs] [Times: user=0.64 sys=0.02, real=0.11 secs] 
[Full GC [PSYoungGen: 3001K->3001K(6656K)] [ParOldGen: 13393K->13377K(13824K)] 16394K->16378K(20480K) [PSPermGen: 3163K->3163K(21504K)], 0.0873232 secs] [Times: user=0.28 sys=0.02, real=0.09 secs] 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2245)
    at java.util.Arrays.copyOf(Arrays.java:2219)
    at java.util.ArrayList.grow(ArrayList.java:242)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:216)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:208)
    at java.util.ArrayList.add(ArrayList.java:440)
    at HeapOOM.main(HeapOOM.java:17)
Heap
 PSYoungGen      total 6656K, used 3144K [0x00000000ff900000, 0x0000000100000000, 0x0000000100000000)
  eden space 6144K, 51% used [0x00000000ff900000,0x00000000ffc12240,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
  to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 ParOldGen       total 13824K, used 13377K [0x00000000feb80000, 0x00000000ff900000, 0x00000000ff900000)
  object space 13824K, 96% used [0x00000000feb80000,0x00000000ff890578,0x00000000ff900000)
 PSPermGen       total 21504K, used 3194K [0x00000000f9980000, 0x00000000fae80000, 0x00000000feb80000)
  object space 21504K, 14% used [0x00000000f9980000,0x00000000f9c9ebc8,0x00000000fae80000)

虛擬機(jī)棧和本地方法棧溢出

public class JavaVMStackSOF {

    private int stackLength=1;

    public void stackLeak(){
        stackLength++;
        stackLeak();
    }

    public static void main(String[] args) {
        JavaVMStackSOF oom = new JavaVMStackSOF();
        try {
            oom.stackLeak();
        } catch (Exception e) {
            System.out.println("e.length:"+oom.stackLength);
            e.printStackTrace();
        }
    }
}
Exception in thread "main" java.lang.StackOverflowError
    at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:6)
    at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7)
    at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7)
    at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7)

方法區(qū)和運(yùn)行時(shí)常量池溢出

前文提到hotspot虛擬機(jī)棧中方法區(qū)是由永久代來實(shí)現(xiàn)的,可以用參數(shù)-XX:PermSize -XX:MaxPermSize來限制其空間,當(dāng)無法申請到足夠的內(nèi)存時(shí),會出現(xiàn)“permgen space”異常。但在jdk1.7中已經(jīng)將永久代的字符串常量池移除,將其移入到Class對象末尾(也就是gc heap)。在jdk1.8將廢除永久代,引用元空間概念,使用native memory來實(shí)現(xiàn),可以通過參數(shù):-XX:MetaspaceSize -XX:MaxMetaspaceSize來指定元空間大小。

/**
 * vm args:-XX:PermSize=4m -XX:MaxPermSize=4m -Xmx6m
 * Created by zhizhanxue on 18-3-26.
 */
public class MethodAreaOOM {

    public static void main(String[] args) {
        long i=0;
        List list = new ArrayList<>();
        while (true){
            list.add(String.valueOf(i++).intern());
        }
    }
}

jdk1.6的運(yùn)行結(jié)果:

jdk1.7的運(yùn)行結(jié)果:

jdk1.8的運(yùn)行結(jié)果:

下面我們來驗(yàn)證下元空間的例子:

/**
*-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=8m
*/
public class SpringTest {

    static class OOM implements MethodInterceptor{

        public Object getInstance(){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(OOM.class);
            enhancer.setCallback(this);
            enhancer.setUseCache(false);
            return enhancer.create();
        }

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            return methodProxy.invoke(o,objects);
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        List list = new ArrayList<>();
        OOM oom = new OOM();
        while (true){
            list.add(oom.getInstance());
        }
    }
   }

運(yùn)行結(jié)果:

本機(jī)直接內(nèi)存溢出

DirectMemory容量可以通過參數(shù)-XX:MaxDirectMemorySize來指定,如果不指定則默認(rèn)與java堆最大值(-Xmx指定一樣),代碼通過unsafe.allocateMemory()去申請堆外內(nèi)存模擬本地內(nèi)存溢出異常。

/**
 * -Xmx220m -XX:MaxDirectMemorySize=10m
 */
public class LocalOOM {

    public static void main(String[] args) throws IllegalAccessException {
        Field field = Unsafe.class.getDeclaredFields()[0];
        field.setAccessible(true);
        Unsafe unsafe = (Unsafe) field.get(null);
        while (true){
            unsafe.allocateMemory(1024*1024);
        }
    }

}

運(yùn)行結(jié)果:

Exception in thread "main" java.lang.OutOfMemoryError
    at sun.misc.Unsafe.allocateMemory(Native Method)
    at LocalOOM.main(LocalOOM.java:12)

由堆外內(nèi)存導(dǎo)致的內(nèi)存溢出,一般都是gc日志很少,且堆dump文件不會看到明顯的異常,如果情況和上述類似,你的項(xiàng)目中又使用了NIO,可以著重檢查下是不是這方面的原因。

下節(jié)預(yù)告

1.對象已死?(如何判斷對象是否存活)
2.垃圾收集的四種基礎(chǔ)算法
3.垃圾收集器的介紹

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/71042.html

相關(guān)文章

  • 深入理解java虛擬機(jī)》學(xué)習(xí)筆記系列——java內(nèi)存區(qū)域劃分

    摘要:運(yùn)行時(shí)數(shù)據(jù)區(qū)域的學(xué)習(xí),是學(xué)習(xí)以及機(jī)制的基礎(chǔ),也是深入理解對象創(chuàng)建及運(yùn)行過程的前提。了解內(nèi)存區(qū)域劃分,是學(xué)習(xí)概念的前提。 Java 運(yùn)行時(shí)數(shù)據(jù)區(qū)域的學(xué)習(xí),是學(xué)習(xí) jvm 以及 GC 機(jī)制的基礎(chǔ),也是深入理解 java 對象創(chuàng)建及運(yùn)行過程的前提。廢話不多說,直接進(jìn)入正題: 一張圖總結(jié) showImg(https://segmentfault.com/img/bVOMAn?w=685&h=5...

    史占廣 評論0 收藏0
  • 深入理解JVM》讀書筆記

    摘要:抽時(shí)間重新讀了一遍深入理解一書。驗(yàn)證確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會危害虛擬機(jī)自身的安全。可見性可見性是指當(dāng)一個(gè)線程修改了共享變量的值,其他線程能夠立即得知這個(gè)修改。 抽時(shí)間重新讀了一遍《深入理解JVM》一書。以下為摘錄內(nèi)容。 1 java內(nèi)存區(qū)域 showImg(https://segmentfault.com/img/bVboDgk?w=617&h=365...

    idealcn 評論0 收藏0
  • JVM系列(一):深入詳解JVM 內(nèi)存區(qū)域總結(jié)!

    摘要:一內(nèi)存區(qū)域虛擬機(jī)在運(yùn)行時(shí),會把內(nèi)存空間分為若干個(gè)區(qū)域,根據(jù)虛擬機(jī)規(guī)范版的規(guī)定,虛擬機(jī)所管理的內(nèi)存區(qū)域分為如下部分方法區(qū)堆內(nèi)存虛擬機(jī)棧本地方法棧程序計(jì)數(shù)器。前言 在JVM的管控下,Java程序員不再需要管理內(nèi)存的分配與釋放,這和在C和C++的世界是完全不一樣的。所以,在JVM的幫助下,Java程序員很少會關(guān)注內(nèi)存泄露和內(nèi)存溢出的問題。但是,一旦JVM發(fā)生這些情況的時(shí)候,如果你不清楚JVM內(nèi)存的...

    Aldous 評論0 收藏0
  • Java虛擬機(jī)學(xué)習(xí)

    摘要:虛擬機(jī)學(xué)習(xí)是一個(gè)虛構(gòu)出來的計(jì)算機(jī)有自己的處理器堆棧寄存器以及相應(yīng)的指令系統(tǒng)等。類裝載器子系統(tǒng)涉及虛擬機(jī)的其它組成部分和來自庫的類。運(yùn)行中的程序的每一個(gè)線程都是一個(gè)獨(dú)立的虛擬機(jī)執(zhí)行引擎的實(shí)例。 Java虛擬機(jī)學(xué)習(xí) JVM JVM是一個(gè)虛構(gòu)出來的計(jì)算機(jī),有自己的處理器,堆棧,寄存器以及相應(yīng)的指令系統(tǒng)等。JVM是JRE的一部分,通過在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能,這樣就能使Java在...

    RobinTang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<