观JVM运行时几种常见内存溢出

本文详细介绍了JVM运行时内存划分的各个区域,包括虚拟机栈、本地方法栈、程序计数器、方法区(JDK8后为元空间)、堆,并通过具体案例演示了这些区域如何触发内存溢出。

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

下图是JVM运行时将内存划分的几个区域,后面总结一下几个区域的内存溢出情况

虚拟机栈:线程私有,用于存储局部变量、操作数栈、动态链接、方法出口等信息
本地方法栈:线程私有,用于JVM执行Native方法时使用
程序计数器:线程私有,是一块较小的内存空间,可以看做是当前线程执行的字节码指示器
方法区:线程共享,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
:线程共享,存储对象实例。

在JDK8后,已经取消了方法区,而是把这些数据存到了元空间(MetaSpace)中,元空间直接使用本地内存

元空间内存溢出 如果在JDK8中使用-XX:PermSize=10m -XX:MaxPermSize=10m 配置VM内存,会得到如下提示

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=10m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=10m; support was removed in 8.0

JDK8已经不存在方法区,而变成了元空间,元空间大小配置 -XX:MetaspaceSize,初始空间大小 -XX:MaxMetaspaceSize,最大空间 将VM配置改为-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m,重新运行出现内存溢出

java.lang.OutOfMemoryError: Metaspace

测试用例

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @author: jujun chen
 * @description: 使用了CGLIB来动态生成类,-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
 * @date: 2019/4/7
 */
public class JavaMetaSpaceOOM {

    static class OOMObject{}

    public static void main(final String[] args) {
        while (true){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(OOMObject.class);
            enhancer.setUseCache(false);
            enhancer.setCallback(new MethodInterceptor() {
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    return methodProxy.invokeSuper(o,objects);
                }
            });
            enhancer.create();
        }
    }

}

堆内存溢出

java.lang.OutOfMemoryError: Java heap space 这是碰到次数最多的溢出

测试用例VM配置为 -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError 可以在虚拟机内存溢出时Dump出当前内存堆,该文件可以用Eclipse Memory Analyzer,或者IDEA JProfiler分析

import java.util.ArrayList;
import java.util.List;

/**
 * @author: jujun chen
 * @description: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
 * @date: 2019/4/7
 */
public class HeapOOM {
    static class OOMObject{}

    public static void main(String[] args) {
        List<OOMObject> list = new ArrayList<OOMObject>();
        while (true){
            list.add(new OOMObject());
        }
    }
}

虚拟机栈和本地方法栈溢出

Exception in thread "main" java.lang.StackOverflowError

测试用例VM配置为 -Xss160k


/**
 * @author: jujun chen
 * @description: -Xss160k
 * @date: 2019/4/7
 */
public class VMStackSOF {
    private int stackLength = 1;
    public void stackLeak(){
        stackLength++;
        stackLeak();
    }

    public static void main(String[] args) {
        VMStackSOF oom = new VMStackSOF();
        oom.stackLeak();
    }
}

参考《深入理解Java虚拟机》

转载于:https://my.oschina.net/itsaysay/blog/3033361

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值