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

資訊專欄INFORMATION COLUMN

論JVM爆炸的幾種姿勢及自救方法

hyuan / 600人閱讀

摘要:方法區溢出在的方法區中,它主要存放了類的信息,常量,靜態變量等。運行結果簡單解決思路一般來說此類問題多出現在存在遞歸的地方,要從代碼里重新審視遞歸未結束的原因,若遞歸的方法沒問題可以根據實際情況調整參數的大小。

前言

如今不管是在面試還是在我們的工作中,OOM總是不斷的出現在我們的視野中,所以我們有必要去了解一下導致OOM的原因以及一些基本的調整方法,大家可以通過下面的事例來了解一下什么樣的代碼會導致OOM,幫助我們以后在工作中能夠通過異常信息來判斷是JVM里面哪個區域出現了問題。

先介紹一下筆者的相關編碼環境。

jdk:java version "1.8.0_121"

ide:IntelliJ IDEA 2019.1 (Community Edition)

正文
1.Java堆溢出

Java中的堆存儲的都是對象實例,當我們不斷的創建對象,而GC的時候又不能回收,當存儲的對象大小超過了-Xmx的值,這時候則會出現OutOfMemoryError.[-XX:+HeapDumpOnOutOfMemoryError]參數可以讓jvm出現內存溢出的時候dump出內存堆轉儲快照。

/**
 * VM Args: -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError
 * @author wangzenghuang
 */
public class HeapOOMDemo {
    public static void main(String[] args) {
        List stringList = new ArrayList<>();
        while(true){
            stringList.add("str");
        }
    }
}

運行結果,發生OOM,并且在我們項目的根目錄dump出當前的內存堆快照

java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid1376.hprof ...
Heap dump file created [7972183 bytes in 0.047 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3210)
    at java.util.Arrays.copyOf(Arrays.java:3181)
    at java.util.ArrayList.grow(ArrayList.java:261)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
    at java.util.ArrayList.add(ArrayList.java:458)
    at HeapOOMDemo.main(HeapOOMDemo.java:12)

Process finished with exit code 1

簡單解決思路

那么發生這個問題以后我們的解決思路有哪些呢?我們可以利用一些工具(例如Eclipse Memory Analyzer
)來分析dump出的文件,一般來說,當生產環境發生OOM,比較常見的一個原因是發生了內存泄漏,用工具可以分析出泄露的對象到GC Root的引用鏈,從而定位到問題代碼。假如經過分析后發現內存中的對象都是“必須存活”的對象,這時候就要思考下項目中是否把“-Xms跟-Xmx”設置得太小了(當然這里也不是隨意調大,需要結合機器的物理內存情況),再者需要留意代碼中是否有一些長生命周期的對象,從代碼中優化內存消耗。

2.方法區溢出

在jvm的方法區中,它主要存放了類的信息,常量,靜態變量等。在jdk8以前是通過“-XX:PermSize,-XX:MaxPermSize”來調整這個區域的值,但是從8開始呢,永久代的概念被MetaSpace(元空間)代替了,對應的參數也變成了“-XX:MetaspaceSize,-XX:MaxMetaspaceSize”。在這個例子中使用CGLib來動態生成一些類,方便我們實驗操作。

/**
 * VM Args: -XX:MetaspaceSize=5m -XX:MaxMetaspaceSize=5m
 * @author wangzenghuang
 */
public class MethodAreaOOMDemo {
    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[] objects, MethodProxy methodProxy) throws Throwable {
                    return methodProxy.invokeSuper(obj,objects);
                }
            });
            enhancer.create();
        }
    }
    static class OOMObject{}
}

運行結果

Exception in thread "main" java.lang.OutOfMemoryError: Metaspace

簡單解決方法

這個問題的話,一般來說根據情況調整方法區的大小就行了,網上也有人說可以去掉MetaSpace的的大小限制,但是不建議這么干,畢竟不可控的事情我們要少點干,很容易給自己埋雷。

3.棧溢出

對于我們來說,還有一個熟悉的錯誤,那就是“StackOverflowError”,它是由線程請求的棧深度超過了jvm允許的最大范圍而產生的。“-Xss”參數可以設置棧容量。

/**
 * VM Args: -Xss128k
 * @author wangzenghuang
 */
public class StackOFDemo {
    private static int stackLength = 1;

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

    public static void main(String[] args) {
        StackOFDemo stackOFDemo = new StackOFDemo();
        try {
            stackOFDemo.stackLeak();
        }catch (Throwable e){
            System.out.println("length : "+ stackLength);
            throw e;
        }
    }
}

運行結果

length : 983
Exception in thread "main" java.lang.StackOverflowError
    at StackOFDemo.stackLeak(StackOFDemo.java:10)
    at StackOFDemo.stackLeak(StackOFDemo.java:10)
    ...

簡單解決思路

一般來說此類問題多出現在存在遞歸的地方,要從代碼里重新審視遞歸未結束的原因,若遞歸的方法沒問題可以根據實際情況調整“-Xss”參數的大小。還有一些代碼的循壞依賴也會造成此類情況,

4.直接內存溢出

本機直接內存默認與“-Xmx”設定的值一樣大,可以通過“-XX:MaxDirectMemorySize”修改。

/**
 * VM Args: -Xmx20m -XX:MaxDirectMemorySize=10
 * @author wangzenghuang
 */
public class DirectMemoryOOMDemo {
    private static final int _1MB = 1024 * 1024;

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

運行結果

呃,一運行這段代碼idea直接閃退了,查閱其他資料可以得知當DirectMemory導致內存溢出時,Heap Dump文件是很小的,如果程序中有使用NIO的情況可以檢查一下。

總結

這里所展示的代碼只是可以觸發jvm的各種錯誤,但是并不代表這是唯一的觸發錯誤的方方式,假如我們的代碼比較復雜,有時候遇到類似錯誤的時候還是需要耐心分析。

文章內容首發于微信公眾號《深夜里的程序猿》,轉載請注明出處,侵權必究。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77495.html

相關文章

  • Java日志正確使用姿勢

    摘要:但是往往越簡單的東西越容易讓我們忽視,從而導致一些不該有的發生,作為一名嚴謹的程序員,怎么能讓這種事情發生呢所以下面我們就來了解一下關于日志的那些正確使用姿勢。級別表示出現了嚴重錯誤,程序將會中斷執行。 前言 關于日志,在大家的印象中都是比較簡單的,只須引入了相關依賴包,剩下的事情就是在項目中盡情的打印我們需要的信息了。但是往往越簡單的東西越容易讓我們忽視,從而導致一些不該有的bug發...

    UCloud 評論0 收藏0
  • 使用ConcurrentHashMap一定線程安全?

    摘要:前言老王為何半夜慘叫幾行代碼為何導致服務器爆炸說好的線程安全為何還是出問題讓我們一起收看今天的走進正文出現背景說到的出現背景,還得從說起。在跟中,都只是調用的方法,各自都是原子操作,是線程安全的。 前言 老王為何半夜慘叫?幾行代碼為何導致服務器爆炸?說好的線程安全為何還是出問題?讓我們一起收看今天的《走進IT》 正文 CurrentHashMap出現背景 說到ConcurrentHas...

    荊兆峰 評論0 收藏0
  • Java核心技術教程整理,長期更新

    以下是Java技術棧微信公眾號發布的關于 Java 的技術干貨,從以下幾個方面匯總。 Java 基礎篇 Java 集合篇 Java 多線程篇 Java JVM篇 Java 進階篇 Java 新特性篇 Java 工具篇 Java 書籍篇 Java基礎篇 8張圖帶你輕松溫習 Java 知識 Java父類強制轉換子類原則 一張圖搞清楚 Java 異常機制 通用唯一標識碼UUID的介紹及使用 字符串...

    Anchorer 評論0 收藏0
  • 聊聊Vue.js組件間通信幾種姿勢

    摘要:子組件向父組件通信方法一使用事件父組件向子組件傳遞事件方法,子組件通過觸發事件,回調給父組件。非父子組件兄弟組件之間的數據傳遞非父子組件通信,官方推薦使用一個實例作為中央事件總線。 寫在前面 因為對Vue.js很感興趣,而且平時工作的技術棧也是Vue.js,這幾個月花了些時間研究學習了一下Vue.js源碼,并做了總結與輸出。 文章的原地址:https://github.com/answ...

    Profeel 評論0 收藏0
  • 異步讀取文件幾種姿勢

    摘要:臆想的針對讀取到的內容進行操作,比如打印文件內容臆想中,讀取文件是有返回值的,將返回值,即文件內容,賦給一個變量,然后決定對讀取到的內容進行相應的操作,例如打印文件中的內容。 臆想的 let fs = require(fs) function readFile(filename){ ... } let content = readFile(config.js) // 針對讀...

    chinafgj 評論0 收藏0

發表評論

0條評論

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