JVM 遇到的问题-1.0

JVM 遇到的问题-1.0

Q1. java 虚拟机规范定义的运行时数据区有几块?分别是什么?

A :一共有5块

B分别是:程序计数器,java 堆,java虚拟机栈,本地方法栈,方法区(jdk8之后改成元空间)。

⚠️ 注意事项

1). 直接内存不属于运行时数据区;

2). jdk7之前方法区实现为永久代PermGen,jdk8之后彻底移除永久代,使用元空间。

3). 程序计时器是唯一没有OOM的内存区域。

Q2.直接内存是什么?又叫什么?

A: 直接内存又称为堆外内存。通过Unsafe向操作系统直接申请的内存,

典型 API:ByteBuffer.allocateDirect(),Netty 大量使用堆外缓冲区。存放 NIO 网络 IO 的数据缓冲区;不在 Java 堆中,不受-Xmx/-Xms限制。

⚠️ 注意事项

  1. 堆上只会生成一个很小的DirectByteBuffer代理对象,真实数据存在堆外;
  2. 依靠Cleaner虚引用异步回收,极易发生堆外内存泄漏;
  3. 调控参数:-XX:MaxDirectMemorySize;OOM 报错:Direct buffer memory。

Q3:JVM 的组成 = 运行时数据区 + 直接内存?

A:这样说,表述不严谨,是不对的。JVM 完整的架构是五大子系统:

类加载子系统,运行时数据区,执行引擎,gc子系统,本地方法接口。

B: 从进程内存占用视角看,JVM 进程使用的内存包含:运行时数据区 + 直接内存。直接内存不属于 JVM 规范定义的运行时数据区,只是排查内存故障时需要一并分析。

Q4:如何系统掌握各区域 OOM 场景,并且动手复现?

1)熟记映射表:异常日志 → 定位内存区域

|------------------------------------|-----------|
| 报错信息 | 对应区域 |
| Java heap space | Java 堆 |
| Metaspace | 元空间 (方法区) |
| Direct buffer memory | 直接内存 |
| unable to create new native thread | 虚拟机栈 |
| StackOverflowError | 虚拟机栈 |

2)每一个 OOM Demo 强制配套 3 组 JVM 参数

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Plain Text # 1. GC日志输出 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log # 2. OOM自动dump堆快照 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=oom.hprof # 3. 限制对应区域内存,稳定复现 |

3)分层练习

① 基础 Demo 复现(while 循环简易案例)

② 模拟业务真实内存泄漏(ThreadLocal、静态缓存、动态类)

③ 使用 MAT 分析 hprof 快照,定位引用链,区分【内存泄漏 / 单纯内存不足】

Q5:OOM 发生之后,JVM 进程一定会退出吗?

A:不一定。

如果代码捕获 OOM 异常,当前线程终止,其他线程可继续运行;持续分配对象会反复抛出 OOM,进程不会直接死掉。

Q6:StackOverflowError 和 OOM 的本质区别?

A:

  • StackOverflowError:单个线程栈空间容量不足,方法调用层级过深;
  • unable to create new native thread OOM:系统资源不足,无法新建线程分配栈内存

Q7:发生堆 OOM,一定是堆太小吗?

A:不一定。两种场景:

  1. 业务流量变大,对象总量上升 → 需要调大堆;
  2. 代码内存泄漏,无用对象持续占用 → 改代码,单纯调堆治标不治本。

Q8:为什么 Netty 优先使用直接内存?

A:减少一次内核缓冲区与 JVM 堆缓冲区的数据拷贝(减少一次内存复制,零拷贝思想,提升 IO 性能);代价是堆外内存管理复杂,容易泄漏。

Q9:程序计数器为什么不会产生 OOM?

A:每条线程的程序计数器只保存一条指令地址,内存占用极小;JVM 规范明确规定此区域不需要回收,不会出现内存溢出。

相关推荐
liangbo75 小时前
JVM规范第 4 章:class 文件格式
java·jvm
夕除6 小时前
redis--008
java·jvm·数据库
liangbo76 小时前
JVM规范第 1章:从一段历史到「JVM 并不认识 Java」
java·jvm
月华路19 小时前
G1 GC 对数组与大对象(Humongous)的处理
java·jvm·算法
月华路1 天前
G1 新生代对象晋升老年代:实现机制与 GC 日志
java·jvm·算法
Shadow(⊙o⊙)1 天前
C++进阶知识5.0
jvm
一木 之林1 天前
五、C++新特性、关键字与编译原理
java·jvm·算法
Mr. zhihao1 天前
线上卡顿排查决策手册:场景 × 命令 × 现象 × 调整方案
java·开发语言·jvm