如何分析和定位Java堆外内存泄漏?

老年代的内存状况也不容忽视。使用jstat -gcold pid和jstat -gcoldcapacity pid可以获取Old代对象的具体信息和容量占用。如果Old代持续快速增长且Full GC后无明显下降,可能意味着存在大对象泄漏或静态集合引用未释放。此外,jstat -gcpermcapacity pid可用于监控Perm代(或元空间)的容量变化,这是堆外内存泄漏的高发区。

评论 (2)

补充一点,除了看jstat,其实结合MAT(Memory Analyzer Tool)导出的heap dump分析引用链会更直观。特别是对于静态集合(比如HashMap未清理)导致的大对象滞留,光靠GC日志有时候很难 pinpoint 具体是哪个类在引用。另外提醒一下,PermGen是JDK8之前的概念,现在主流JDK8+都是元空间(Metaspace),虽然都在堆外,但监控命令和表现略有不同,注意区分版本。

补充一点,其实Perm/Metaspace严格来说不算纯粹的堆外内存,而是直接内存(Direct Memory)的一种特殊形式。很多人会混淆Direct ByteBuf和Metaspace,排查时容易走弯路。另外,Old代泄漏除了静态集合,还要警惕ThreadLocal没移除导致的内存无法回收,这个坑踩的人不少。