国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

JVM 各區(qū)域的用途以及潛在出現(xiàn)異常的示例

2019-11-11 07:14:28
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

學(xué)習(xí)java的同學(xué)注意了!??! 學(xué)習(xí)過(guò)程中遇到什么問(wèn)題或者想獲取學(xué)習(xí)資源的話,歡迎加入Java學(xué)習(xí)交流群,群號(hào)碼:183993990  我們一起學(xué)Java!

程序計(jì)數(shù)器

用于給字節(jié)碼解釋器來(lái)選取嚇一跳需要執(zhí)行的字節(jié)碼指令。每個(gè)線程有一個(gè)獨(dú)立的程序計(jì)數(shù)器去,且各個(gè)線程之間互不影響。如果線程正在執(zhí)行一個(gè)Java方法,這個(gè)計(jì)數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的內(nèi)存地址;如果執(zhí)行的是Native方法。在計(jì)數(shù)器為Undefined。此區(qū)域是JVM規(guī)范中唯一一個(gè)不存在OOM的區(qū)域

虛擬機(jī)棧(局部變量空間)

存放編譯器可知的各種基本數(shù)據(jù)類型(boolean、byte、char、short、int、float、long、double)、對(duì)象應(yīng)用(reference)。64位的double、long占用2個(gè)槽。內(nèi)存空間在編譯期間就能確定,當(dāng)進(jìn)入一個(gè)方式時(shí),這個(gè)方法需要分配的局部變量空間是完全確定的,通過(guò)-Xss設(shè)置內(nèi)存容量

異常狀況:

StackOverflowError 棧深度大于虛擬機(jī)所允許的深度

OOM 如果虛擬機(jī)??梢詣?dòng)態(tài)擴(kuò)展(當(dāng)前大部分Java虛擬機(jī)都可以動(dòng)態(tài)擴(kuò)展,只不過(guò)Java虛擬機(jī)規(guī)范中的也允許固定長(zhǎng)度的虛擬機(jī)棧),如果擴(kuò)展是無(wú)法申請(qǐng)到足夠的內(nèi)存

在單個(gè)線程下,無(wú)論是猶豫棧幀太大還是虛擬機(jī)棧容量太小,當(dāng)內(nèi)存無(wú)法分配的時(shí)候,虛擬機(jī)拋出的都是StackOverflowError

/*** VM Args:-Xss128k* * stack length:2402 Exception in thread "main" java.lang.StackOverflowError*/public class JavaVMStackSOF {PRivate int stackLength = 1;public void stackLeak() {    stackLength++;    stackLeak();}public static void main(String[] args) throws Throwable {    JavaVMStackSOF oom = new JavaVMStackSOF();    try {        oom.stackLeak();    } catch (Throwable e) {        System.out.println("stack length:" + oom.stackLength);        throw e;    }}}

如果測(cè)試時(shí)不限于單線程,通過(guò)不斷的建立線程的方式到是可以產(chǎn)生內(nèi)存溢出的異常。但是這樣產(chǎn)生的內(nèi)存溢出異常與占空間是否足夠大并不存在任何聯(lián)系,或者準(zhǔn)確的說(shuō),在這種情況下,為每個(gè)線程的棧分配的內(nèi)存越大,反而越容易產(chǎn)生內(nèi)存溢出的異常。

因?yàn)?a href="http://m.survivalescaperooms.com/system.asp">操作系統(tǒng)分配給每個(gè)進(jìn)程的內(nèi)存是有限制的,譬如32的window限制為2GB。此測(cè)試是通過(guò)創(chuàng)建大量的線程。每個(gè)線程占用棧內(nèi)存分配大量的內(nèi)存,導(dǎo)致系統(tǒng)沒(méi)有足夠的內(nèi)存。使其不能自動(dòng)擴(kuò)展

/** * VM Args:-Xss2M (這時(shí)候不妨設(shè)大些) * * java.lang.OutOfMemoryError:unable to create new native thread */public class JavaVMStackOOM {       private void dontStop() {              while (true) {              }       }       public void stackLeakByThread() {              while (true) {                     Thread thread = new Thread(new Runnable() {                            @Override                            public void run() {                                   dontStop();                            }                     });                     thread.start();              }       }       public static void main(String[] args) throws Throwable {              JavaVMStackOOM oom = new JavaVMStackOOM();              oom.stackLeakByThread();       }}

本地方法棧

跟虛擬機(jī)棧類似,只是一個(gè)是虛擬機(jī)執(zhí)行Java方法,一個(gè)是執(zhí)行Native方法

異常狀況:

StackOverflowError 棧深度大于虛擬機(jī)所允許的深度

OOM

Java堆

線程共享的一塊內(nèi)存區(qū)域,從內(nèi)存回收角度來(lái)看,基本都采用分代收集算法,所以分為新生代、老年代。再細(xì)致一點(diǎn)可以分為Eden空間、From Survivor空間、To Survivor空間等。-Xmx -Xms控制堆空間大小

異常狀況:

1.OOM 堆無(wú)法擴(kuò)展時(shí)

/** * VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError *  * java.lang.OutOfMemoryError: Java heap space */public class HeapOOM {    static class OOMObject {    }    public static void main(String[] args) {        List<OOMObject> list = new ArrayList<OOMObject>();        while (true) {            list.add(new OOMObject());        }    }}

方法區(qū)

線程間共享。存儲(chǔ)已經(jīng)被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編輯器編譯后的代碼等數(shù)據(jù),在HotSpot虛擬機(jī)中可以稱為永生代。

運(yùn)行時(shí)常量在1.6及之前是方法區(qū)的一部分(String.intern()動(dòng)態(tài)加入常量池) -XX:MaxPermSize控制大小。在JDK1.7及之后的版本是在Java堆中開(kāi)辟的一塊內(nèi)存

異常狀況:

OOM

/*** 需要在JDK1.6上才能復(fù)現(xiàn),JDK1.7及之后版本的JVM已經(jīng)將運(yùn)行時(shí)常量池從方法區(qū)中移了出來(lái),在Java 堆(Heap)中開(kāi)辟了一塊區(qū)域存放運(yùn)行時(shí)常量池。* 在JDK1.7上運(yùn)行的效果則會(huì)一直執(zhí)行,直到堆內(nèi)存使用完畢* VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M ** java.lang.OutOfMemoryError:PermGen space*/public class RuntimeConstantPoolOOM {public static void main(String[] args) {    // 使用List保持著常量池引用,避免Full GC回收常量池行為    List<String> list = new ArrayList<String>();    // 10MB的PermSize在integer范圍內(nèi)足夠產(chǎn)生OOM了    int i = 0;    while (true) {        list.add(String.valueOf(i++).intern());    }}}
/*** VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M* java.lang.OutOfMemoryError:PermGen space* 一直創(chuàng)建動(dòng)態(tài)類*/public class JavaMethodAreaOOM {public static void main(String[] args) {    while (true) {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(OOMObject.class);        enhancer.setUseCache(false);        enhancer.setCallback(new MethodInterceptor() {            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {                return proxy.invokeSuper(obj, args);            }        });        enhancer.create();    }}static class OOMObject {}}

直接內(nèi)存(不屬于虛擬機(jī)運(yùn)行時(shí)的數(shù)據(jù)區(qū)的一部分)

NIO可以使用Native函數(shù)庫(kù)直接分配對(duì)外的內(nèi)存,然后通過(guò)存儲(chǔ)在Java對(duì)中的DirectByteBuffer對(duì)象作為這塊內(nèi)存的引用進(jìn)行操作。受限于機(jī)器物理內(nèi)存,可以通過(guò)-XX:MaxDirectMemorySize制定,如果不制定,默認(rèn)與Java堆最大值(-Xmx)一樣

異常狀況:

1.OOM

/** * VM Args:-Xmx20M -XX:MaxDirectMemorySize=10M *  * java.lang.OutOfMemoryError */public class DirectMemoryOOM {    private static final int _1MB = 1024 * 1024;    public static void main(String[] args) throws Exception {        Field unsafeField = Unsafe.class.getDeclaredFields()[0];        unsafeField.setaccessible(true);        Unsafe unsafe = (Unsafe) unsafeField.get(null);        while (true) {            unsafe.allocateMemory(_1MB);        }    }}

學(xué)習(xí)Java的同學(xué)注意了?。?! 學(xué)習(xí)過(guò)程中遇到什么問(wèn)題或者想獲取學(xué)習(xí)資源的話,歡迎加入Java學(xué)習(xí)交流群,群號(hào)碼:183993990  我們一起學(xué)Java!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 佛坪县| 错那县| 舞阳县| 渝北区| 桂平市| 博乐市| 申扎县| 营山县| 陈巴尔虎旗| 广河县| 含山县| 沅陵县| 枣强县| 呼图壁县| 门头沟区| 兰州市| 钟山县| 齐齐哈尔市| 麟游县| 平安县| 金塔县| 桦川县| 彰化县| 栾川县| 汉源县| 泾源县| 山西省| 巢湖市| 崇义县| 万宁市| 即墨市| 江阴市| 吉安市| 望奎县| 萍乡市| 太谷县| 濮阳县| 攀枝花市| 板桥市| 安龙县| 濮阳县|