java总结-内存泄漏

内存泄漏现象

  • 堆内存(Heap)持续增长,最终触发 OutOfMemoryError(OOM)内存溢出。
  • 频繁 Full GC,但可用内存无法释放。
  • 应用程序响应变慢,甚至无响应。

 

分析步骤

获取pid

ps -ef | grep 'myServerName'

查看jvm分配内存

jinfo -flags <pid>

 

查看运行项目的内存使用情况和垃圾回收情况

jstat -gc <pid> 1000 5

输出包含了JVM垃圾收集的详细统计信息

  • 1000: 每1000毫秒(1秒)采样一次
  • 5: 总共采样5次

S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
1024.0 1024.0  0.0   512.0   8192.0   4096.0   20480.0    10240.0   4480.0 4224.0 384.0  352.0    10    0.523    2     0.845    1.368

 

各字段详细解释

年轻代(Young Generation)相关:

  • S0C: Survivor 0区容量(KB)
  • S1C: Survivor 1区容量(KB)
  • S0U: Survivor 0区已使用空间(KB)
  • S1U: Survivor 1区已使用空间(KB)
  • EC: Eden区容量(KB)
  • EU: Eden区已使用空间(KB)

老年代(Old Generation)相关:

  • OC: 老年代容量(KB)
  • OU: 老年代已使用空间(KB)

元空间(Metaspace)相关:

  • MC: 元空间容量(KB)
  • MU: 元空间已使用空间(KB)
  • CCSC: 压缩类空间容量(KB)
  • CCSU: 压缩类空间已使用空间(KB)

垃圾收集统计:

  • YGC: 年轻代GC次数
  • YGCT: 年轻代GC总耗时(秒)
  • FGC: Full GC次数
  • FGCT: Full GC总耗时(秒)
  • GCT: GC总耗时(秒)

比如这个结果:

年轻代(Young Generation):
- S0C/S1C: 0.0/1024.0 KB (Survivor区容量)
- S0U/S1U: 0.0/1024.0 KB (Survivor区使用量)
- EC: 1,516,544.0 KB ≈ 1.45GB (Eden区容量)
- EU: 1,141,760.0 KB ≈ 1.09GB (Eden区使用量)

老年代(Old Generation):
- OC: 1,418,240.0 KB ≈ 1.35GB (老年代容量)
- OU: 1,417,486.6 KB ≈ 1.35GB (老年代使用量)

元空间(Metaspace):
- MC: 169,164.0 KB ≈ 165MB (元空间容量)
- MU: 157,850.4 KB ≈ 154MB (元空间使用量)

1. 严重的老年代内存压力
老年代使用率:1,417,486.6 / 1,418,240.0 ≈ 99.95%
几乎完全占用,存在严重的内存泄漏风险

2. 频繁的Full GC
FGC: 33次
FGCT: 149.684秒
平均每次Full GC耗时:149.684/33 ≈ 4.5秒

3. GC效率低下
YGC: 219次(年轻代GC)
YGCT: 11.928秒
总GC时间:161.611秒
GC时间占比:161.611/(运行时间) ≈ 很高比例

 

转存堆存储文件

如果发现如果老年代(Old Gen)或永久代/元空间(PermGen/Metaspace)持续增长,占用情况严重可能是内存泄漏。

可以进行转存堆存储文件进行分析

  • jmp方式
jmap -dump:live,format=b,file=heap_dump.hprof <pid>
或
jmap -dump:format=b,file=heap_dump.hprof <pid>

包含live参数,先执行一次 Full GC(导致应用暂停时间更长),只保存 GC 后仍然存活的对象,过滤掉所有可回收的临时对象(可能丢失一些即将被回收的大对象信息)

不包含live参数,不会额外触发 GC,文件更大(包含大量临时对象),分析时噪音更多,但有助于分析内存溢出,大量临时对象也可能造成内存溢出

  • 启动参数方式 

也可以在启动参数中加上如下配置,当发生OOM时会生成堆存储文件

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/path/to/dumps/

 

  •  jcmd方式

或使用 jcmd 命令(推荐,JDK 7+)

比 jmap 更友好,不会暂停 JVM,支持更多选项

 语法
jcmd <pid> GC.heap_dump <输出文件路径>

# 示例
jcmd 12257 GC.heap_dump /tmp/heap_dump.hprof

# 示例:生成到当前目录
jcmd 12257 GC.heap_dump ./heap_dump.hprof

对堆存储文件进行分析

Eclipse MAT

免费

下载地址:https://eclipse.dev/mat/

下载下来提示至少jdk17,兼容jdk8

在安装目录下打开MemoryAnalyzer.ini文件

image

在最顶部,加入下面两行来制定jdk目录中的javaw的目录

-vm
D:\jdk1.8.0_121\bin\javaw.exe

image

 

JProfiler

文档:https://www.ej-technologies.com/resources/jprofiler/v/16.0/help_zh_CN/doc/main/memory.html

收费,有试用天数

image

image

 

 

比如选中第一个右键

image

查看引用的地方

 

image

 

Java VisualVM

命令行运行下面命令进行打开,或直接双击JDK安装目录下的jvisualvm.exe。

jvisualvm

 

posted @ 2026-03-03 17:47  星光闪闪  阅读(0)  评论(0)    收藏  举报