模拟JVM栈溢出和堆溢出

  • 内存溢出:程序无法申请到可用的内存
  • 内存泄漏:程序占用的内存无法释放

JVM参数中,设置堆内存大小:

  • -Xms 最小堆内存
  • -Xmx 最大堆内存
  • 堆中创建了太多对象来不及被GC回收掉时,程序还在继续申请内存,创建对象时,就会出现OutOfMemoryError
  • 可以通过把堆内存设置的很小,然后创建一个大对象直到把堆内存撑爆模拟
    在这里插入图片描述
/**
 * 模拟堆内存溢出
 */
public class OutOfMemoryTest {

    public static void main(String[] args) {
        List<User> list = new ArrayList<>();
        //- 循环创建的实例对象被list引用,所以无法被GC回收
        for(int i =0;;i++){
            System.out.println("轮次:" + i);
            list.add(new User(UUID.randomUUID().toString()));
        }
    }

    public static class User {
        private String id;
        public User(String id){
            this.id = id;
        }
        public String getId() {
            return id;
        }
    }

}

设置线程栈内存小:

  • -Xss 一个线程堆栈的最大内存容量,可以容纳很多栈帧,设置太大时,系统创建的线程就有限,设置过小时,方法调用过深时会出现栈内存溢出(StackOverflowError),不同于堆内存中存储很多实例,栈中存的引用地址居多(JDK7后默认开启逃逸分析,JIT即时编译优化后,也会在栈内存上创建实例对象,这样明显减少了堆中的GC次数),还有局部变量等,所以占用空间相对小很多,除非调用链很深很深,或者死循环这种,超过了可用栈深度。
/**
 * 模拟栈内存溢出
 */
public class StackOverflowTest {

    private static int count = 0;

    public static void main(String[] args) {
        test();
    }

    /**
     * 递归调用自己,直到栈溢出
     */
    public static void test(){
        System.out.println(String.format("调用深度:%d,id:%s", count, UUID.randomUUID().toString()));
        count++;
        test();
    }

}

阅读参考:对象并不一定都在堆内存上分配,https://blog.csdn.net/w372426096/article/details/80333657

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值