暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

java内存溢出(二)

架构师肖邦 2018-04-28
353

一、有哪些内存溢出异常?

OutOfMemoryError:

当堆、栈(多线程场景)、方法区(永久区)、本地内存(元数据、直接内存),数据容量达到最大时产生

StackOverFlowError:

线程请求的栈深度大于虚拟机栈允许的最大深度(默认1MB)时产生

二、堆溢出产生原因及解决方法?

 产生原因:

不停的创建对象或对象占用空间特别大,在对象数量达到堆最大容量时产生OutOfMemoryError  

 解决方法:

使用-XX:+HeapDumpOnOutOfMemoryError,可以让java虚拟机在出现内存溢出时,产生当前堆内存快照以便进行异常分析,主要分析哪些对象占用了内存

代码示例: 

/**

 * 描    述:堆内存溢出

 * 作    者:潇邦

 */

public class HeapOOM {

    public static void main(String[] args) {

        int i = 0;

        List<String> list = new ArrayList<>();

        while (true) {

            list.add("abc");

            i++;

        }

    }

}

 

三、栈溢出产生原因及解决方法?

产生原因:

    线程请求的栈深度大于虚拟机允许的最大深度,将抛出StockOverFlowError 

多线程环境虚拟机栈在扩展时无法申请到足够内存空间,将抛出OutOfMemoryError 

解决方法:

StockOverFlowError:一般函数层级过多导致,如死循环、死递归

OutOfMemoryError:一般多线程环境产生才会产生,一般用减少内存的方法,即减少栈容量来换取更多线程。

该参数可以设置栈容量(-XX:ThreadStackSize=512)

单线程栈代码示例:

/**

 * 描    述:栈内存溢出StackOverflowError

 * 作    者:潇邦

 */

public class StackOverFlow {

    private int var;


    public void run() {

        var++;

        run();

    }


    public static void main(String[] args) {

        StackOverFlow stackOverFlow = new StackOverFlow();

        try {

            stackOverFlow.run();

        } catch (Exception e) {

            System.out.println("Exception-栈深度:" + stackOverFlow.var);

            e.printStackTrace();

        } catch (Error e) {

            System.out.println("Error-栈深度:" + stackOverFlow.var);

            e.printStackTrace();

        }

    }

}   

多线程栈代码示例:  

/**

 * 描    述:多线程环境栈引发OutOfMemoryError

 * 作    者:潇邦

 */

public class StackOom {


    public void call() {

        try {

            Thread.sleep(10000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }


    public void stackLeakByThread() {

        while (true) {

            new Thread(new Runnable() {

                public void run() {

                    call();

                }

            }).start();

        }

    }


    public static void main(String[] args) {

        StackOom soed = new StackOom();

        soed.stackLeakByThread();

    }

}

 

 

 


文章转载自架构师肖邦,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论