麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

JVM 各區域的用途以及潛在出現異常的示例

2019-11-14 09:00:11
字體:
來源:轉載
供稿:網友

學習java的同學注意了!!! 學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:183993990  我們一起學Java!

程序計數器

用于給字節碼解釋器來選取嚇一跳需要執行的字節碼指令。每個線程有一個獨立的程序計數器去,且各個線程之間互不影響。如果線程正在執行一個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的內存地址;如果執行的是Native方法。在計數器為Undefined。此區域是JVM規范中唯一一個不存在OOM的區域

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

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

異常狀況:

StackOverflowError 棧深度大于虛擬機所允許的深度

OOM 如果虛擬機棧可以動態擴展(當前大部分Java虛擬機都可以動態擴展,只不過Java虛擬機規范中的也允許固定長度的虛擬機棧),如果擴展是無法申請到足夠的內存

在單個線程下,無論是猶豫棧幀太大還是虛擬機棧容量太小,當內存無法分配的時候,虛擬機拋出的都是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;    }}}

如果測試時不限于單線程,通過不斷的建立線程的方式到是可以產生內存溢出的異常。但是這樣產生的內存溢出異常與占空間是否足夠大并不存在任何聯系,或者準確的說,在這種情況下,為每個線程的棧分配的內存越大,反而越容易產生內存溢出的異常。

因為操作系統分配給每個進程的內存是有限制的,譬如32的window限制為2GB。此測試是通過創建大量的線程。每個線程占用棧內存分配大量的內存,導致系統沒有足夠的內存。使其不能自動擴展

/** * VM Args:-Xss2M (這時候不妨設大些) * * 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();       }}

本地方法棧

跟虛擬機棧類似,只是一個是虛擬機執行Java方法,一個是執行Native方法

異常狀況:

StackOverflowError 棧深度大于虛擬機所允許的深度

OOM

Java堆

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

異常狀況:

1.OOM 堆無法擴展時

/** * 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());        }    }}

方法區

線程間共享。存儲已經被虛擬機加載的類信息、常量、靜態變量、即時編輯器編譯后的代碼等數據,在HotSpot虛擬機中可以稱為永生代。

運行時常量在1.6及之前是方法區的一部分(String.intern()動態加入常量池) -XX:MaxPermSize控制大小。在JDK1.7及之后的版本是在Java堆中開辟的一塊內存

異常狀況:

OOM

/*** 需要在JDK1.6上才能復現,JDK1.7及之后版本的JVM已經將運行時常量池從方法區中移了出來,在Java 堆(Heap)中開辟了一塊區域存放運行時常量池。* 在JDK1.7上運行的效果則會一直執行,直到堆內存使用完畢* 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范圍內足夠產生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* 一直創建動態類*/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 {}}

直接內存(不屬于虛擬機運行時的數據區的一部分)

NIO可以使用Native函數庫直接分配對外的內存,然后通過存儲在Java對中的DirectByteBuffer對象作為這塊內存的引用進行操作。受限于機器物理內存,可以通過-XX:MaxDirectMemorySize制定,如果不制定,默認與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);        }    }}

學習Java的同學注意了!!! 學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:183993990  我們一起學Java!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 成人短视频在线观看 | www.69色| 性欧美极品xxxx欧美一区二区 | 羞羞视频免费观看网站 | 成人视屏在线观看 | 免看黄大片aa | 日韩精品免费一区二区三区 | 欧美成人免费一区二区三区 | 最新欧美精品一区二区三区 | 91真视频| 黄色片免费看网站 | 国产精品中文在线 | 成人做爰高潮片免费视频韩国 | 在火车上摸两乳爽的大叫 | 国产精品91在线 | 久久久国产精品成人免费 | 久久777国产线看观看精品 | 深夜精品福利 | 激情毛片| 久久成人免费观看 | 亚洲精品动漫在线观看 | 亚洲成人精品视频 | 欧美国产成人在线 | 伦一区二区三区中文字幕v亚洲 | 毛片免费在线观看 | 国产精品一区二区三区在线播放 | 激情毛片 | 精品国产一区二区三区在线观看 | 久久精品99北条麻妃 | 成人男女啪啪免费观看网站四虎 | 亚洲网视频 | 国产精品视频免费网站 | 国产福利视频 | 国产精品久久久久久久午夜片 | 一级大片久久 | 87成人免费看片 | 成人男男视频拍拍拍在线观看 | 欧美www| 极品大长腿啪啪高潮露脸 | 欧美日韩亚洲视频 | 电影av在线 |