讲师中心 微信公众号
AI工具推荐 视频效率加速

Java虚拟机OOM解析

小辰姑娘_9209

小辰姑娘_9209

发布时间:2025-06-25 09:58:16

|

478人浏览过

|

来源于php中文网

原创

[注:本文内容摘选自作者之前的博客]

对于以Java为核心的企业级应用开发,Java虚拟机(JVM)是项目架构的核心。只有深入理解其内存分配和垃圾回收机制,才能在项目建设中得心应手,无论是基于当前流行的微服务架构(如Spring Cloud或Dubbo),还是即将(或已经)流行的服务网格体系。

不多废话,先看一张Java虚拟机的内存体系结构图:

Java虚拟机OOM解析 注:本文主要基于Oracle JDK体系进行阐述

此图主要针对Java Lang Out Of Memory Error异常进行了适当调整,因为核心问题和要素可以通过此图展示。本文主要解析OOM异常,若想深入了解Java虚拟机的相关知识,可参考官方文档。

立即学习“Java免费学习笔记(深入)”;

当我们的应用程序因Java虚拟机内存分配异常时,会抛出java.lang.OutOfMemoryError错误。以下结合实际项目经验,总结了常见的OOM原因及其解决方法,如有遗漏或错误,欢迎补充指正。

1、Java Heap Space

此情况表明当堆内存(Heap Space)没有足够空间存放新创建的对象时,会抛出java.lang.OutOfMemoryError: Java heap space错误。

原因分析

Java heap space错误的常见原因包括以下几类:

1、请求创建一个超大对象,通常是一个大数组

2、超出预期的访问量/数据量,通常是上游系统请求流量飙升

3、过度使用终结器(Finalizer),该对象没有立即被GC

4、内存泄漏(Memory Leak),大量对象引用没有释放,JVM无法自动回收,常见于使用File等资源未回收

解决方案

针对大多数情况,通常只需通过-Xmx参数增加JVM堆内存空间即可。如果问题仍然存在,可以参考以下情况进行进一步处理:

1、如果是超大对象,检查其合理性,例如是否一次性查询了数据库全部结果,而没有限制结果数量。

2、如果是业务峰值压力,可以考虑增加机器资源或进行限流降级。

3、如果是内存泄漏,需要找到持有的对象,优化代码设计。

2、GC overhead limit exceeded

此情况为JDK1.6新增的错误类型。如果没有此异常,会发生什么?垃圾回收释放的2%可用内存空间会迅速被填满,迫使GC再次执行,导致频繁执行GC操作,服务器会因为频繁的GC操作达到100%的使用率,运行变慢,应用系统会出现卡顿现象,通常几毫秒可完成的操作,现在需要更长时间,甚至几分钟才能完成。

原因分析

1、垃圾回收可用空间较小

2、频繁执行GC操作,使得资源使用率较高

解决方案

1、增加heap堆内存

2、增加内存后错误依旧,获取heap内存快照,使用Eclipse MAT工具,找出内存泄露并进行修复

3、优化代码以使用更少的内存或重用对象,而不是创建新的对象,从而减少垃圾收集器的运行次数。如果代码中在循环中创建了许多临时对象,应该尝试重用它们

4、升级JDK到1.8,至少也是1.7,并使用G1 GC垃圾回收算法

5、优化代码

3、Unable to create new native thread

每个Java线程都需要占用一定的内存空间,当JVM向底层操作系统请求创建一个新的native线程时,如果没有足够的资源分配就会报此类错误。

原因分析

JVM向OS请求创建native线程失败,就会抛出Unable to create new native thread错误,常见原因包括以下几类:

1、线程数超过操作系统最大线程数ulimit限制

2、线程数超过kernel.pid_max(只能重启)

3、native内存不足

解决方案

1、升级配置,为机器提供更多的内存

2、降低Java Heap Space大小

3、修复应用程序的线程泄漏问题

4、限制线程池大小

5、使用-Xss参数减少线程栈的大小

6、调高OS层面的线程最大数:执行ulimit -a查看最大线程数限制,使用ulimit -u xxx调整最大线程数限制

4、Out of swap space?

此错误表示所有可用的虚拟内存已被耗尽。虚拟内存(Virtual Memory)由物理内存(Physical Memory)和交换空间(Swap Space)组成。当程序运行时请求的虚拟内存溢出时,会报Out of swap space错误。

原因分析

此错误出现的常见原因包括以下几类:

1、地址空间不足

2、物理内存已耗光

deep-java-review
deep-java-review

Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...

下载

3、应用程序的本地内存泄漏(native leak),例如不断申请本地内存却不释放

4、执行jmap -histo:live 命令,强制执行Full GC;如果几次执行后内存明显下降,则基本确认为Direct ByteBuffer问题

解决方案

根据错误原因可以采取如下解决方案:

1、升级地址空间为64 bit

2、使用Arthas检查是否为Inflater/Deflater解压缩问题,如果是,则显式调用end方法

3、Direct ByteBuffer问题可以通过启动参数-XX:MaxDirectMemorySize调低阈值

4、升级服务器配置/隔离部署,避免争用

5、Kill process or sacrifice child

有一种内核作业(Kernel Job)称为Out of Memory Killer,它会在可用内存极低的情况下“杀死”(kill)某些进程。OOM Killer会对所有进程进行评分,然后将评分较低的进程“杀死”,具体的评分规则可以参考Surviving the Linux OOM Killer。

不同于其他的OOM错误,Kill process or sacrifice child错误不是由JVM层面触发的,而是由操作系统层面触发的。

原因分析

1、默认情况下,Linux内核允许进程申请的内存总量大于系统可用内存,通过这种“错峰复用”的方式可以更有效地利用系统资源

2、然而,这种方式也会无可避免地带来一定的“超卖”风险。例如某些进程持续占用系统内存,然后导致其他进程没有可用内存。此时,系统将自动激活OOM Killer,寻找评分低的进程,并将其“杀死”,释放内存资源

解决方案

1、升级服务器配置/隔离部署,避免争用

2、OOM Killer调优

6、Requested array size exceeds VM limit

JVM限制了数组的最大长度,此错误表示程序请求创建的数组超过最大长度限制。JVM在为数组分配内存前,会检查要分配的数据结构在系统中是否可寻址,通常为Integer.MAX_VALUE-2。

此类问题比较罕见,通常需要检查代码,确认业务是否需要创建如此大的数组,是否可以拆分为多个块,分批执行。

7、Direct buffer memory

Java允许应用程序通过Direct ByteBuffer直接访问堆外内存,许多高性能程序通过Direct ByteBuffer结合内存映射文件(Memory Mapped File)实现高速IO。

原因分析

Direct ByteBuffer的默认大小为64 MB,一旦使用超出限制,就会抛出Direct buffer memory错误。

解决方案

1、Java只能通过ByteBuffer.allocateDirect方法使用Direct ByteBuffer,因此,可以通过Arthas等在线诊断工具拦截该方法进行排查

2、检查是否直接或间接使用了NIO,如netty,jetty等

3、通过启动参数-XX:MaxDirectMemorySize调整Direct ByteBuffer的上限值

4、检查JVM参数是否有-XX:+DisableExplicitGC选项,如果有就去掉,因为该参数会使System.gc()失效

5、检查堆外内存使用代码,确认是否存在内存泄漏;或者通过反射调用sun.misc.Cleaner的clean()方法来主动释放被Direct ByteBuffer持有的内存空间

6、内存容量确实不足,升级配置

8、Permgen space

此错误表示永久代(Permanent Generation)已用满,通常是因为加载的class数目太多或体积太大。

原因分析

永久代存储对象主要包括以下几类:

1、加载/缓存到内存中的class定义,包括类的名称,字段,方法和字节码

2、常量池

3、对象数组/类型数组所关联的class

4、JIT编译器优化后的class信息[PermGen的使用量与加载到内存的class的数量/大小正相关]

解决方案

根据Permgen space报错的时机,可以采用不同的解决方案,如下所示:

1、程序启动报错,修改-XX:MaxPermSize启动参数,调大永久代空间

2、应用重新部署时报错,很可能是应用没有重启,导致加载了多份class信息,只需重启JVM即可解决

3、运行时报错,应用程序可能会动态创建大量class,而这些class的生命周期很短暂,但是JVM默认不会卸载class,可以设置-XX:+CMSClassUnloadingEnabled和-XX:+UseConcMarkSweepGC这两个参数允许JVM卸载class

9、Metaspace

原因分析

JDK1.8使用Metaspace替换了永久代(Permanent Generation),此错误表示Metaspace已被用满,通常是因为加载的class数目太多或体积太大。

解决方案

此类问题的原因与解决方法跟Permgen space非常类似,可以参考上文。需要特别注意的是调整Metaspace空间大小的启动参数为-XX:MaxMetaspaceSize。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

2211

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

417

2026.01.26

Java 微服务与 Spring Cloud 实战
Java 微服务与 Spring Cloud 实战

本专题讲解 Java 微服务架构的开发与实践,重点使用 Spring Cloud 实现服务注册与发现、负载均衡、熔断与限流、分布式配置管理、API Gateway 和消息队列。通过实际项目案例,帮助开发者理解 如何将传统单体应用拆分为高可用、可扩展的微服务架构,并有效管理和调度分布式系统中的各个组件。

308

2026.02.05

Java Spring Cloud微服务配置中心与服务治理实践
Java Spring Cloud微服务配置中心与服务治理实践

本专题围绕 Java 微服务体系中的配置管理与服务治理展开,重点讲解 Spring Cloud 在分布式系统中的核心组件应用。内容涵盖配置中心设计、服务注册与发现、负载均衡、熔断降级以及分布式配置动态刷新机制。通过实际项目案例,帮助开发者构建高可用、易扩展的微服务架构体系。

234

2026.04.07

eclipse教程
eclipse教程

php中文网为大家带来eclipse教程合集,eclipse是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。php中文网还为大家带来eclipse的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

570

2023.06.14

eclipse怎么设置中文
eclipse怎么设置中文

eclipse设置中文的方法:除了设置界面为中文外,你还可以为Eclipse添加中文插件,以便更好地支持中文编程。例如,你可以安装EBNF插件来支持中文变量名,或安装Chinese Helper来提供中文帮助文档。本专题为大家提供eclipse设置中文相关的各种文章、以及下载和课程。

4706

2023.07.24

c语言编程软件有哪些
c语言编程软件有哪些

c语言编程软件有GCC、Clang、Microsoft Visual Studio、Eclipse、NetBeans、Dev-C++、Code::Blocks、KDevelop、Sublime Text和Atom。更多关于c语言编程软件的问题详情请看本专题的文章。php中文网欢迎大家前来学习。

7139

2023.11.02

Eclipse版本号有哪些区别
Eclipse版本号有哪些区别

区别:1、Eclipse 3.x系列:Eclipse的早期版本,包括3.0、3.1、3.2等;2、Eclipse 4.x系列:Eclipse的最新版本,包括4.0、4.1、4.2等;3、Eclipse IDE for Java Developers等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2764

2024.02.23

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

160

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn