• java内存溢出(二)


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

    OutOfMemoryError:

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

    StackOverFlowError:

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

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

     产生原因:

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

     解决方法:

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

    代码示例:

     1 import java.util.ArrayList;
     2 import java.util.List;
     3 
     4 /**
     5  * 描    述:堆内存溢出
     6  * 作    者:潇邦
     7  */
     8 public class HeapOOM {
     9 
    10     public static void main(String[] args) {
    11         int i = 0;
    12         List<String> list = new ArrayList<>();
    13         while (true) {
    14             list.add("abc");
    15             i++;
    16         }
    17     }
    18 
    19 }

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

    产生原因:

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

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

    解决方法:

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

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

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

    单线程栈代码示例:

     1 /**
     2  * 描    述:栈内存溢出StackOverflowError
     3  * 作    者:潇邦
     4  */
     5 public class StackOverFlow {
     6     private int var;
     7 
     8     public void run() {
     9         var++;
    10         run();
    11     }
    12 
    13     public static void main(String[] args) {
    14         StackOverFlow stackOverFlow = new StackOverFlow();
    15         try {
    16             stackOverFlow.run();
    17         } catch (Exception e) {
    18             System.out.println("Exception-栈深度:" + stackOverFlow.var);
    19             e.printStackTrace();
    20         } catch (Error e) {
    21             System.out.println("Error-栈深度:" + stackOverFlow.var);
    22             e.printStackTrace();
    23         }
    24     }
    25 }

    多线程栈代码示例: 

     1 /**
     2  * 描    述:多线程环境栈引发OutOfMemoryError
     3  * 作    者:潇邦
     4  */
     5 public class StackOom {
     6 
     7     public void call() {
     8         try {
     9             Thread.sleep(10000);
    10         } catch (InterruptedException e) {
    11             e.printStackTrace();
    12         }
    13     }
    14 
    15     public void stackLeakByThread() {
    16         while (true) {
    17             new Thread(new Runnable() {
    18                 public void run() {
    19                     call();
    20                 }
    21             }).start();
    22         }
    23     }
    24 
    25     public static void main(String[] args) {
    26         StackOom soed = new StackOom();
    27         soed.stackLeakByThread();
    28     }
    29 }

     

    版权声明:本文版权归作者java潇邦和博客园和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    庆祝一下开通了第一条博客!
    查看树莓派温度
    Ubuntu Server for Raspberry Pi部署Jenkins
    acme.sh部署RSA、ECC双证书(使用阿里云API)
    Ubuntu Server 20.04换用阿里源
    ESP32使用NTP同步时间
    C语言的可变参数函数
    一种Θ(1)的计算32位整数二进制中1的个数的方法
    CentOS 8安装Docker
    CentOS 8搭建LNMP + WordPress(三)
  • 原文地址:https://www.cnblogs.com/sunrisexq/p/8644544.html
Copyright © 2020-2023  润新知