JVM内存区域异常实战

本文详细解析了Java程序中常见的内存异常现象,包括StackOverflowError和OutOfMemoryError等,并通过示例代码展示了如何触发这些异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内存中可能出现的异常

异常点StackOverflowErrorOutOfMemoryError
PC
VM Stack请求栈深度过大可动态扩展栈情况下,无法申请足够的内存
Native MethodStack同上同上
Heap创建对象时无法申请足够的内存
Method Area无法满足内存分配需求时
运行时常量池常量池无法再申请到内存时
直接内存(直接内存不是VM运行时数据区的一部分,也不是JVM规范中定义的内存区域,不受JVM内存限制但受宿主机的内存限制仍会出异常)

注:虚拟机配置参数: -Xmx10m (部分地方如果不配置参数可能要很久才会抛出异常)

虚拟机栈异常

虚拟机栈 StackOverflowError

public class StackOverflowExcetpionTest {

   public static void main(String[] args) {

       method();
  }

   public static void method() {

       method(); // 本地代码中此行为22行,对应下边异常堆栈信息的行号
   }
}

Exception in thread “main” java.lang.StackOverflowError
at cn.com.OutOfMemoryError.StackOverflowExcetpionTest.method(StackOverflowExcetpionTest.java:22)
at cn.com.OutOfMemoryError.StackOverflowExcetpionTest.method(StackOverflowExcetpionTest.java:22)

虚拟机栈 OutOfMemoryError

public class StackOverflowExcetpionTest {

   public static void main(String[] args) {

       method2();              // 行号13
   }

   public static void method2(){

       List list = new ArrayList<>();
       while(true){
           list.add(new double[10000]);      // 行号:20 
       }
   }
}    

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
at cn.com.OutOfMemoryError.StackOverflowExcetpionTest.method2(StackOverflowExcetpionTest.java:20)
at cn.com.OutOfMemoryError.StackOverflowExcetpionTest.main(StackOverflowExcetpionTest.java:13)

本地方法栈异常

// TODO

堆区异常

堆区异常只有 OutOfMemoryError异常

public class StackOverflowExcetpionTest {

   public static void main(String[] args) {

       method3();     // 行号13
   }

   public static void method3(){

       List list = new ArrayList<>();
       while(true){
           list.add(new StackOverflowExcetpionTest());   // 行号:20
       }
   }
}

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 cn.com.OutOfMemoryError.StackOverflowExcetpionTest.method3(StackOverflowExcetpionTest.java:20)
at cn.com.OutOfMemoryError.StackOverflowExcetpionTest.main(StackOverflowExcetpionTest.java:13)

方法区异常/常量池异常

方法区异常只有 OutOfMemoryError

 // JDK1.6及以下(JDK1.7可以用反射动态加载class,直至异常)
 // 此处虚拟机配置   -Xmx1m
 public class Main {

  public static void main(String[] args) {
      method4();   // 行号:8
  }
  public static void method4(){
      // 指定大小防止因为ArrayList扩充时进行复制需要分配内存而导致出现堆区的OOM异常
      List<String> list = new ArrayList<String>(10000);
      int count = 0;
      while(true){
          count++;
          // add里的部分生成字符串并将字符串放入运行时常量池(在方法区、也叫持久区)
          // 字符串放入常量池的操作JDK1.7之后与 <=1.6版本的处理方式不一样
          // 因此此实验在<=JDK1.6才会成功
          list.add((count+"xxxxxxxxxxxx"+count).intern());   // 行号:19
      }
  }
}

Exception in thread “main” java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at Main.method4(Main.java:19)
at Main.main(Main.java:8)

直接内存异常

这个是由于虚拟机设置的内存大于系统内存,而程序运行时确实需要很大的内存时JVM向OS申请内存失败

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值