JVM 内存溢出

一次 Java 进程 OOM 的排查分析(glibc 篇) 遇到了一个 glibc 导致的内存回收问题,查找原因和实验的的过程是比较有意思的,主要会涉及到下面这些: Linux 中典型的大量 64M 内存区域问题 glibc 的内存分配器 ptmalloc2 的底层原理 如何写一个自定义的 malloc hook 动态链接库 so glibc 的内存分配原理(Arena、Chunk 结构、bins 等) malloc_trim 对内存真正回收的影响 gd... 阅读详情

在实际编程过程中,会遇到一些OutOfMemory(OOM)异常。通过模拟。我们可以直接指出这些场景的本质,从而在纷繁复杂的千万行代码中避免这样去Coding。导致OOM的情况有多种,包括Java或Native Method Stack的内存不足或者栈空间溢出、Heap内存溢出、Non-heap内存溢出、Direct Memory溢出。

1.Java Method Stack栈溢出模拟

什么时候会让Java Method Stack栈溢出?栈的基本特点就是FILO(First In Last Out),如果in的太多而out的太少,就可能overflow了。而Java Method Statck的功能就是保存每一次函数调用时的“现场”,即为入栈,函数返回对应出栈,所以函数的调用深度越大,栈就变得越大,足够大的时候就会溢出。所以模拟Java Method Stack溢出,只要不断递归调用某一函数就可以导致溢出。
[java] view plaincopy
package com.jony.java;

public class TestStackOverflow {
private int stackLength = 0;

public void stackOverFlow(){  
    ++stackLength;  
    stackOverFlow();  
}  

public static void main(String[] args){  
    TestStackOverflow test = new TestStackOverflow();  
    try {  
        test.stackOverFlow();  
    } catch (Throwable e) {  
        System.out.println("Stack Length:" + test.stackLength);  
        e.printStackTrace();  
    }  
}  

}
运行结果:
Stack Length:11477
java.lang.StackOverflowError
at com.jony.java.TestStackOverflow.stackOverFlow(TestStackOverflow.java:7)
at com.jony.java.TestStackOverflow.stackOverFlow(TestStackOverflow.java:8)
at com.jony.java.TestStackOverflow.stackOverFlow(TestStackOverflow.java:8)
at com.jony.java.TestStackOverflow.stackOverFlow(TestStackOverflow.java:8)
at com.jony.java.TestStackOverflow.stackOverFlow(TestStackOverflow.java:8)
at com.jony.java.TestStackOverflow.stackOverFlow(TestStackOverflow.java:8)
at com.jony.java.TestStackOverflow.stackOverFlow(TestStackOverflow.java:8)
at com.jony.java.TestStackOverflow.stackOverFlow(TestStackOverflow.java:8)
at com.jony.java.TestStackOverflow.stackOverFlow(TestStackOverflow.java:8)

2. Java Method Stack内存溢出模拟-Heap内存溢出

堆是用来存储对象的,当然对象不一定都存在堆里(栈上分配、标量替换技术)。那么堆如果溢出了,一定是不能被杀掉的对象太多了。模拟Heap内存溢出,只要不断的创建对象并保存对象引用存在即可。
[java] view plaincopy
package com.jony.java;

import java.util.ArrayList;

public class TestHeapOverflow {

static class TestOomHeap {}  

public static void main(String[] args) {  
    ArrayList<TestOomHeap> list = new ArrayList<TestHeapOverflow.TestOomHeap>();  

    while (true) {  
        list.add(new TestOomHeap());  
    }  
}  

}
运行结果:
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
at com.jony.java.TestHeapOverflow.main(TestHeapOverflow.java:13)

3. Method Area内存溢出

Method Area内存溢出,也就是Non-heap,是用来存储Object Class Data、变量、静态常量、JIT编译后的代码。如果该区域溢出,则说明某种数据创建的实在是太多了,模拟该异常,可以不断创建新的class,知道溢出为止。下面实例中会用到asm-all-3.0.jar和cglib2.2.jar 下载
[java] view plaincopy
package com.jony.java;

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class TestMethodAreaOverflow {

static class MethodAreaOom {}  

public static void main(String[] args) {  
    while (true) {  
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(MethodAreaOom.class);  
        enhancer.setUseCache(false);  
        enhancer.setCallback(new MethodInterceptor() {  

            @Override  
            public Object intercept(Object arg0, Method arg1, Object[] arg2,  
                    MethodProxy proxy) throws Throwable {  
                return proxy.invoke(arg0, arg2);  
            }  
        });  
        enhancer.create();  
    }  
}  

}
运行结果:
Exception in thread “main” net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException–>null
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at com.jony.java.TestMethodAreaOverflow.main(TestMethodAreaOverflow.java:26)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
… 3 more
Caused by: java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
… 8 more

4.Runtime Constant Pool In Method Area溢出

在运行时产生大量常量就可以让Method Area溢出,运行时常量可以用String类的intern方法,不断产生新的常量。
[java] view plaincopy
package com.jony.java;

import java.util.ArrayList;

public class RCPverflow {

public static void main(String[] args) {  
    ArrayList<String> list = new ArrayList<String>();  
    int i = 0;  
    while (true) {  
        list.add(String.valueOf(i++).intern());  
    }  
}  

}
运行结果:
Exception in thread “main” java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at com.jony.java.RCPverflow.main(RCPverflow.java:11)

总结

在实际编程中要尽量避免此类错误,不过大多数程序设计的结构要比实例复杂很多,使得问题被应藏,但JVM内存溢出问题本质上就是以上几种问题,因此在实际编程中应该避免JVM内存溢出情况。

Java中JVM内存溢出问题的解决方法 在深入探讨内存溢出问题之前,了解JVM的内存区域划分是很有必要的。堆内存(Heap):用于存储对象实例,是垃圾回收(GC)的主要管理区域。堆内存又分为年轻代(Young Generation)和老年代(Old Generation)。方法区(Method Area):用于存储类的元数据、常量、静态变量等信息。在Java 8之前,方法区也被称为永久代(PermGen);在Java 8及之后,永久代被元空间(Metaspace)取代。栈内存(Stack) 阅读详情

相关推荐

JVM内存溢出监控自动化

1:手动生成Java heap dump首先需要搞懂什么是java heap,java heap是分配给实例类和数组对象运行数据区,所有java线程在运行期间共享heap中的数据。Java heap dump相当于java应用在运行的时候在某个时间点上打了个快照(snapshot)。启动一个JAVA项目,环境变量配置了JDK环境 jps命令是jdk用来查看java进程的命令,252是当前正在运行的j

IsResultXaL的博客 2867

JVM:堆(Heap)和非堆(Non-heap)内存

jvm

blueheartstone的博客 3118

从帧结构到数据解析:深入理解CJ/T 188 MBUS水表通信协议

本文深入解析CJ/T 188 MBUS水表通信协议,从帧结构到数据解析提供完整指南。通过典型报文示例和实战案例,详细讲解地址域、控制码、数据标识符(DI)等关键字段的解析技巧,并分享校验算法与常见错误排查方法,帮助开发者快速掌握MBUS协议在水表通信中的应用。

weixin_28710999的博客 421

JVM学习之:堆(Heap)和非堆(Non-heap)内存

堆(Heap)和非堆(Non-heap)内存: 堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。 简单来说堆就是Java代码可及的内存,是留给开发人员使用的; 非堆就是JVM留给 自己用的,所有方法区、JVM内部处理或优化所需的内存...

shun12580的博客 2万+

基于RTL8367S与XS2184的工业级POE交换机硬件设计全解析

本文深入解析基于RTL8367S与XS2184芯片的工业级POE交换机硬件设计,涵盖核心价值、芯片选型、原理图设计、PCB布局及可靠性验证等关键环节。重点探讨双芯片协同工作优势,如RTL8367S的自适应调度算法和XS2184的智能功率分配功能,为工业环境下的稳定供电与数据传输提供专业解决方案。

weixin_42614269的博客 458

音频质量评估指标全解析:从主观到客观的全面指南

本文全面解析了音频质量评估的核心指标,涵盖主观评价(如MOS、DMOS)与客观评价(如PESQ、STOI、SDR)。重点介绍了DNSMOS等AI驱动的无参考评估方法,并提供了根据语音通信、噪声抑制、语音分离等不同场景选择指标组合的实战指南,帮助开发者和研究者科学量化音频质量。

rum55的博客 641

JVM - 内存区域与内存溢出异常

程序计数器:一块较小的内存空间,当前线程所执行的字节码的行号指示器。Java栈也称作虚拟机栈、栈内存,为JVM执行Java方法(也就是字节码)服务。 Ø 本地方法栈(native)。Java堆(Heap)。 方法区(Non-Heap)

Lupu's journey - 生活、分享 201

Spring WebFlux响应式编程实战(三):优雅处理异常与高效调试技巧

本文深入探讨了Spring WebFlux响应式编程中的异常处理与调试技巧。文章通过电商订单流处理场景,详细解析了Reactor核心操作符onErrorReturn、onErrorResume和onErrorMap的实战应用,并介绍了如何构建@ControllerAdvice和WebExceptionHandler全局异常处理防线。同时,提供了使用.log()操作符、Hooks.onOperatorDebug()及BlockHound进行高效调试的方法,旨在帮助开发者构建健壮、可维护的响应式应用。

weixin_29252171的博客 65

java 进程占用系统内存过高分析

JVM的内存 先放一张JVM的内存划分图,总体上可以分为堆和非堆(粗略划分,基于java8) 那么一个Java进程最大占用的物理内存为: Max Memory = eden + survivor + old + String Constant Pool + Code cache + compressed class space + Metaspace + Thread st......

fxh13579的专栏 1万+

STM32F407 CanOpen主机实战:对象字典配置与多电机CIA402协议驱动详解

本文详细介绍了基于STM32F407的CanOpen主机开发实战,重点解析了对象字典的配置流程与多电机CIA402协议驱动方法。通过使用objdictedit工具配置SDO和PDO参数,并整合CanFestival协议栈,实现了对多个伺服电机的稳定同步控制。文章提供了从硬件连接到代码调试的完整指南,帮助开发者快速掌握工业现场的多轴运动控制技术。

plant的博客 527

工作之余的随想:AI 会终结 SAP 顾问吗?

本文是笔者工作之余的一些胡思乱想。昨晚(准确的说是今日凌晨),我又熬了一个夜。没办法,接到一个影响客户项目上线的紧急 incident,花了我好长时间,竟然一点头绪都没有。苦苦思索的过程,时间过得飞快。一转眼就晚上11:30 了。要说我 2007 年还在研三实习期间,就进入了 SAP 行业,到今天已经摸爬滚打 18 年了,按理说也算身经百战了,可以说处理过很多 SAP 客户使用系统时遇到的各种稀奇古怪的问题。但即便这样,我也时常在工作中遇到一开始感到无从下手的问题。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1262

JVM 内存溢出排查

JVM 内存溢出排查

小何的博客 1788

Arcgis栅格裁剪批处理工具

Arcgis栅格裁剪批处理工具

yilvyangguang520的博客 2172

定位jvm内存溢出

生产环境JVM内存溢出案例分析 中间件兴趣圈 中间件兴趣圈 微信号dingwpmz_zjj 功能介绍关注后端技术架构、java多线程、并发、Netty、Mycat、Dubbo、ElasticJob、RocketMQ、Elasticsearch等中间件技术。 前天 如果我们所在公司的业务量比较大,在生产环境经常会出现JVM内存溢出的现象,那我们该如何快速响应,快速定位,快速恢复问题呢? ...

my java博客园 5199

22h2版本的win10安装Docker Desktop时页面空白

摘要:Windows10 22H2系统重装Docker时出现安装界面卡死问题,通过管理员CMD执行静默安装命令解决。命令指定了WSL-2后端及多个自定义数据存储路径(安装目录、Hyper-V数据、Windows容器数据、WSL数据),安装需等待几分钟。最终验证安装成功。

猿小白的博客 650

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

JVM内存溢出排查

如果是方法区内存溢出,可能是因为使用了过多的静态变量、常量池被大量占用,或者第三方框架(如Hibernate、Spring)产生了大量的动态类。这些工具可以帮助识别哪些对象占用了过多的内存,以及这些对象是如何被引用的。通过查看GC日志,可以了解垃圾回收的情况,包括回收的频率、回收的对象数量等。内存泄露是导致内存溢出的常见原因。通过工具分析堆转储文件,可以检查是否存在无用的对象被长时间持有引用,导致无法被GC回收。如果堆内存确实不足,可以考虑调整JVM的启动参数,如增加-Xmx参数的值以增大堆内存的最大值。

程序猿踩坑集锦 994

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Jvm 内存溢出跟踪

JVM的错误之中,java.lang.OutOfMemoryError当属最常见,很多新手对此手无举措,只能各种所搜,配置-Xms -Xmx参数来增加内存,却找不到溢出的原因,其实JDK本身的工具为我们提供了内存溢出的跟踪方法, 这里我们建立一个简单的Demo演示下; 一,首先我们要主动的让Jvm内存溢出,这里我们建立个简单的java_project,结构如下: 在test类中,我们制造...

挖坑大王 1433

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

JVM 内存溢出 java heap space

前段时间公司的项目突然出现了异常,查看日志出现 java.lang.OutOfMemoryError: Java heap space 这不是内存溢出了?当看到这个时候,瞬间想到了JVM调优,这不是面试官最喜欢问的JVM调优? 对JVM没有了解过,刚好项目遇到了,决定学习一波。 首先就是要了解JVM,了解JVM前,需要了解内存模型,类加载机制等;才能更明白的理解JVM,内存模型,类加载机制等,由于时间原因,没有独立的做单独的文章。后续补上。 一:首先了解JVM: JVM它是Java Virtual Ma

sebeefe的博客 9908

OutOfMemoryError内存溢出相关的JVM参数

原文在这里: OutOfMemoryError内存溢出相关的JVM参数 JVM提供了很多处理内存溢出的相关参数,本文主要来讲解下这些参数,当你遇到内存溢出的时候可能会对你非常有帮助,这些参数主要有: 1.-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath 2.-XX:OnOutOfMemoryError 3.-XX:+ExitOnOutOfMemor...

若鱼的专栏 7107

JVM内存溢出的几种方式与解决方法

内存溢出 JVM运行时首先需要类加载器(classLoader)加载所需类的字节码文件。加载完毕交由执行引擎执行,在执行过程中需要一段空间来存储数据(类比CPU与主存)。这段内存空间的分配和释放过程正是我们需要关心的运行时数据区。内存溢出的情况就是从类加载器加载的时候开始出现的,内存溢出分为两大类:OutOfMemoryError和StackOverflowError。以下举出10个内存溢出的情况,并通过实例代码的方式讲解了是如何出现内存溢出的。 java堆内存溢出 当出现java.lang.OutOfMe

Artisan_w 1万+

【jvm】转载 OutOfMemoryError内存溢出相关的JVM参数

JVM提供了很多处理内存溢出的相关参数,本文主要来讲解下这些参数,当你遇到内存溢出的时候可能会对你非常有帮助,这些参数主要有: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath .-XX:OnOutOfMemoryError -XX:+ExitOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError 下面我们来详细的看下每个参数的意义和用法。 1.-XX:+HeapDumpOnOutOfMemoryEr

Mrerlou的博客 1199

JVM 内存溢出 详解

OOM 类型触发原因解决方案堆内存溢出对象过多/内存泄漏调整-Xmx,优化代码元空间溢出动态类过多限制栈溢出(线程数过多)线程数超出系统限制使用线程池,调整-Xss直接内存溢出NIO 分配过多直接内存调整通过jstatjmapjstack监控内存使用。生成堆转储文件(),用 MAT 分析内存泄漏。避免过度依赖反射、动态代理等易触发元空间问题的技术。如何避免 OOM?1. 堆内存溢出• 诊断工具:​ • 使用jvisualvmMAT。

2402_82958989的博客 1864

JVM内存溢出问题总结

JVM的内存溢出问题,是个常见而有时候有非常难以定位的问题。定位内存溢出问题常见方法有很多,但是其实很多情况下可供你选择的有效手段非常有限。很多方法在一些实际场景下没有实用价值。这里总结下我的一些定位思路。 要定位JVM内存溢出问题,首先要对JVM的内存布局有一定的了解,对常见的JVM内存工具要比较熟悉。所谓工欲善其事,必先利其器。而熟悉JVM的内存管理机制是你定位JVM内存问题的基石。首先

E的小小地方 594

JVM方法区内存溢出详解

JVM方法区内存溢出详解

嗨,欢迎来到我的 优快云 博客小天地!一名深耕多年的技术发烧友。在这里,我将把日常工作中积累的宝贵经验,从复杂架构设计的精妙之处,到代码优化的实战技巧,毫无保留地分享给大家。 1793

JVM调优 - JVM内存溢出

如果你做TCP通讯或者map集合操作,并发处理等功能时,很容易出现 Java 内存溢出的问题。本篇文章,带领大家深入jvm,分析并找出jvm内存溢出的代码。 jvm中除了程序计数器,其他的区域都有可能会发生内存溢出 内存溢出是什么 当程序需要申请内存的时候,由于没有足够的内存,此时就会抛出OutOfMemoryError,这就是内存溢出 内存溢出和内存泄漏有什么区别 内存泄漏是由于使用不当,把一部分内存“丢掉了”,导致这部分内存不可用。 当在堆中创建了对象,后来没有使用这个对象了,又没有把整个对象的相关引用

龙鱼618博客 329
上一篇: JAVA8 Lambda表达式
下一篇: JAVA 内存区域
jamespengo
博客等级 码龄16年 83粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值