日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

工作中最常見的六種OOM問題

來源: 責編: 時間:2024-03-18 09:35:54 172觀看
導讀前言今天接著線上問題這個話題,跟大家一起聊聊線上服務出現OOM問題的6種場景,希望對你會有所幫助。1.堆內存OOM堆內存OOM是最常見的OOM了。出現堆內存OOM問題的異常信息如下:java.lang.OutOfMemoryError: Java heap spac

jOy28資訊網——每日最新資訊28at.com

前言

今天接著線上問題這個話題,跟大家一起聊聊線上服務出現OOM問題的6種場景,希望對你會有所幫助。jOy28資訊網——每日最新資訊28at.com

jOy28資訊網——每日最新資訊28at.com

1.堆內存OOM

堆內存OOM是最常見的OOM了。jOy28資訊網——每日最新資訊28at.com

出現堆內存OOM問題的異常信息如下:jOy28資訊網——每日最新資訊28at.com

java.lang.OutOfMemoryError: Java heap space

此OOM是由于JVM中heap的最大值,已經不能滿足需求了。jOy28資訊網——每日最新資訊28at.com

舉個例子:jOy28資訊網——每日最新資訊28at.com

public class HeapOOMTest {    public static void main(String[] args) {        List<HeapOOMTest> list = Lists.newArrayList();        while (true) {            list.add(new HeapOOMTest());        }    }}

這里創建了一個list集合,在一個死循環中不停往里面添加對象。jOy28資訊網——每日最新資訊28at.com

執行結果:jOy28資訊網——每日最新資訊28at.com

jOy28資訊網——每日最新資訊28at.com

出現了java.lang.OutOfMemoryError: Java heap space的堆內存溢出。jOy28資訊網——每日最新資訊28at.com

很多時候,excel一次導出大量的數據,獲取在程序中一次性查詢的數據太多,都可能會出現這種OOM問題。jOy28資訊網——每日最新資訊28at.com

我們在日常工作中一定要避免這種情況。jOy28資訊網——每日最新資訊28at.com

2.棧內存OOM

有時候,我們的業務系統創建了太多的線程,可能會導致棧內存OOM。jOy28資訊網——每日最新資訊28at.com

出現堆內存OOM問題的異常信息如下:jOy28資訊網——每日最新資訊28at.com

java.lang.OutOfMemoryError: unable to create new native thread

給大家舉個例子:jOy28資訊網——每日最新資訊28at.com

public class StackOOMTest {    public static void main(String[] args) {        while (true) {            new Thread().start();        }    }}

使用一個死循環不停創建線程,導致系統產生了大量的線程。jOy28資訊網——每日最新資訊28at.com

執行結果:jOy28資訊網——每日最新資訊28at.com

jOy28資訊網——每日最新資訊28at.com

如果實際工作中,出現這個問題,一般是由于創建的線程太多,或者設置的單個線程占用內存空間太大導致的。jOy28資訊網——每日最新資訊28at.com

建議在日常工作中,多用線程池,少自己創建線程,防止出現這個OOM。jOy28資訊網——每日最新資訊28at.com

3.棧內存溢出

我們在業務代碼中可能會經常寫一些遞歸調用,如果遞歸的深度超過了JVM允許的最大深度,可能會出現棧內存溢出問題。jOy28資訊網——每日最新資訊28at.com

出現棧內存溢出問題的異常信息如下:jOy28資訊網——每日最新資訊28at.com

java.lang.StackOverflowError

例如:jOy28資訊網——每日最新資訊28at.com

public class StackFlowTest {    public static void main(String[] args) {        doSamething();    }    private static void doSamething() {        doSamething();    }}

執行結果:jOy28資訊網——每日最新資訊28at.com

jOy28資訊網——每日最新資訊28at.com

出現了java.lang.StackOverflowError棧溢出的錯誤。jOy28資訊網——每日最新資訊28at.com

我們在寫遞歸代碼時,一定要考慮遞歸深度。即使是使用parentId一層層往上找的邏輯,也最好加一個參數控制遞歸深度。防止因為數據問題導致無限遞歸的情況,比如:id和parentId的值相等。jOy28資訊網——每日最新資訊28at.com

4.直接內存OOM

直接內存不是虛擬機運行時數據區的一部分,也不是《Java虛擬機規范》中定義的內存區域。jOy28資訊網——每日最新資訊28at.com

它來源于NIO,通過存在堆中的DirectByteBuffer操作Native內存,是屬于堆外內存,可以直接向系統申請的內存空間。jOy28資訊網——每日最新資訊28at.com

出現直接內存OOM問題時異常信息如下:jOy28資訊網——每日最新資訊28at.com

java.lang.OutOfMemoryError: Direct buffer memory

例如下面這樣的:jOy28資訊網——每日最新資訊28at.com

public class DirectOOMTest {    private static final int BUFFER = 1024 * 1024 * 20;    public static void main(String[] args) {        ArrayList<ByteBuffer> list = new ArrayList<>();        int count = 0;        try {            while (true) {                // 使用直接內存                ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);                list.add(byteBuffer);                count++;                try {                    Thread.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        } finally {            System.out.println(count);        }    }}

執行結果:jOy28資訊網——每日最新資訊28at.com

jOy28資訊網——每日最新資訊28at.com

會看到報出來java.lang.OutOfMemoryError: Direct buffer memory直接內存空間不足的異常。jOy28資訊網——每日最新資訊28at.com

5.GC OOM

GC OOM是由于JVM在GC時,對象過多,導致內存溢出,建議調整GC的策略。jOy28資訊網——每日最新資訊28at.com

出現GC OOM問題時異常信息如下:jOy28資訊網——每日最新資訊28at.com

java.lang.OutOfMemoryError: GC overhead limit exceeded

為了方便測試,我先將idea中的最大和最小堆大小都設置成10M:jOy28資訊網——每日最新資訊28at.com

-Xmx10m -Xms10m

例如下面這個例子:jOy28資訊網——每日最新資訊28at.com

public class GCOverheadOOM {    public static void main(String[] args) {        ExecutorService executor = Executors.newFixedThreadPool(5);        for (int i = 0; i < Integer.MAX_VALUE; i++) {            executor.execute(() -> {                try {                    Thread.sleep(10000);                } catch (InterruptedException e) {                }            });        }    }}

執行結果:jOy28資訊網——每日最新資訊28at.com

jOy28資訊網——每日最新資訊28at.com

出現這個問題是由于JVM在GC的時候,對象太多,就會報這個錯誤。jOy28資訊網——每日最新資訊28at.com

我們需要改變GC的策略。jOy28資訊網——每日最新資訊28at.com

在老代80%時就是開始GC,并且將-XX:SurvivorRatio(-XX:SurvivorRatio=8)和-XX:NewRatio(-XX:NewRatio=4)設置的更合理。jOy28資訊網——每日最新資訊28at.com

6.元空間OOM

JDK8之后使用Metaspace來代替永久代,Metaspace是方法區在HotSpot中的實現。jOy28資訊網——每日最新資訊28at.com

Metaspace不在虛擬機內存中,而是使用本地內存也就是在JDK8中的ClassMetadata,被存儲在叫做Metaspace的native memory。jOy28資訊網——每日最新資訊28at.com

出現元空間OOM問題時異常信息如下:jOy28資訊網——每日最新資訊28at.com

java.lang.OutOfMemoryError: Metaspace

為了方便測試,我修改一下idea中的JVM參數,增加下面的配置:jOy28資訊網——每日最新資訊28at.com

-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m

指定了元空間和最大元空間都是10M。jOy28資訊網——每日最新資訊28at.com

接下來,看看下面這個例子:jOy28資訊網——每日最新資訊28at.com

public class MetaspaceOOMTest {    static class OOM {    }    public static void main(String[] args) {        int i = 0;        try {            while (true) {                i++;                Enhancer enhancer = new Enhancer();                enhancer.setSuperclass(OOM.class);                enhancer.setUseCache(false);                enhancer.setCallback(new MethodInterceptor() {                    @Override                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {                        return methodProxy.invokeSuper(o, args);                    }                });                enhancer.create();            }        } catch (Throwable e) {            e.printStackTrace();        }    }}

執行結果:jOy28資訊網——每日最新資訊28at.com

jOy28資訊網——每日最新資訊28at.com

程序最后會報java.lang.OutOfMemoryError: Metaspace的元空間OOM。jOy28資訊網——每日最新資訊28at.com

這個問題一般是由于加載到內存中的類太多,或者類的體積太大導致的。jOy28資訊網——每日最新資訊28at.com

好了,今天的內容先分享到這里,下一篇文章重點給大家講講,如何用工具定位OOM問題,敬請期待。jOy28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-76484-0.html工作中最常見的六種OOM問題

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 寫了個簡單爬蟲,收集 Boss直聘自動駕駛崗位

下一篇: 沒看過ReentrantLock源碼,別說精通Java并發編程

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 慈溪市| 来凤县| 旺苍县| 吴桥县| 镇坪县| 葫芦岛市| 通道| 乌审旗| 友谊县| 西乌珠穆沁旗| 思茅市| 耿马| 元朗区| 县级市| 重庆市| 大兴区| 通城县| 孟州市| 台南市| 阳新县| 五河县| 思南县| 垣曲县| 临桂县| 富顺县| 昂仁县| 句容市| 临澧县| 丘北县| 高雄县| 吴忠市| 策勒县| 嘉义县| 泸水县| 南宫市| 汾阳市| 长沙市| 武川县| 罗甸县| 寿光市| 镇江市|