【JAVA】-观JVM运行时几种常见内存溢出

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

image.png

下图是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虚拟机》,如果有不对的地方请指正,谢谢

相关文章
|
7天前
|
存储 算法 Java
JVM自动内存管理之垃圾收集算法
文章概述了JVM内存管理和垃圾收集的基本概念,提供一个关于JVM内存管理和垃圾收集的基础理解框架。
JVM自动内存管理之垃圾收集算法
|
7天前
|
存储 Java 程序员
JVM自动内存管理之运行时内存区
这篇文章详细解释了JVM运行时数据区的各个组成部分及其作用,有助于理解Java程序运行时的内存布局和管理机制。
JVM自动内存管理之运行时内存区
|
7天前
|
Java PHP 数据安全/隐私保护
Java——IDEA如何运行单个文件
Java——IDEA如何运行单个文件
16 1
Java——IDEA如何运行单个文件
|
19天前
|
存储 安全 Java
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别;什么是程序计数器,堆,虚拟机栈,栈内存溢出,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
|
1天前
|
Java Docker 索引
记录一次索引未建立、继而引发一系列的问题、包含索引创建失败、虚拟机中JVM虚拟机内存满的情况
这篇文章记录了作者在分布式微服务项目中遇到的一系列问题,起因是商品服务检索接口测试失败,原因是Elasticsearch索引未找到。文章详细描述了解决过程中遇到的几个关键问题:分词器的安装、Elasticsearch内存溢出的处理,以及最终成功创建`gulimall_product`索引的步骤。作者还分享了使用Postman测试接口的经历,并强调了问题解决过程中遇到的挑战和所花费的时间。
|
6天前
|
存储 安全 Java
JVM内存结构
这篇文章详细介绍了Java虚拟机(JVM)的内存结构,包括类的加载过程、类加载器的双亲委派机制、沙箱安全机制、程序计数器、Java栈、Java堆、本地方法和本地方法栈等关键组件及其作用。
JVM内存结构
|
17天前
|
存储 Java 编译器
Java内存区域与内存溢出异常 - 运行时数据区
【8月更文挑战第2天】Java运行时数据区包括:1) 程序计数器:记录线程执行字节码的行号,线程私有;2) Java虚拟机栈:描述方法执行的内存模型,线程私有,深度过大抛出`StackOverflowError`;3) 本地方法栈:服务于Native方法,线程私有;4) Java堆:所有线程共享,对象实例在此分配内存;5) 方法区:存储类信息、常量等数据;6) 运行时常量池:方法区的一部分,存放字面量和符号引用。不当使用如无限创建对象或过度递归调用会导致各种内存溢出错误。
|
5天前
|
Oracle Java 关系型数据库
简单记录在Linux上安装JDK环境的步骤,以及解决运行Java程序时出现Error Could not find or load main class XXX问题
本文记录了在Linux系统上安装JDK环境的步骤,并提供了解决运行Java程序时出现的"Error Could not find or load main class XXX"问题的方案,主要是通过重新配置和刷新JDK环境变量来解决。
17 0
|
6天前
|
Java Linux Nacos
Java -jar 运行 报 MalformedInputException: Input length = 1
Java -jar 运行 报 MalformedInputException: Input length = 1
7 0
|
6天前
|
算法 Java
JVM自动内存管理之垃圾收集器
这篇文章是关于Java虚拟机(JVM)自动内存管理中的垃圾收集器的详细介绍。