1. 定位内存泄漏根源
jmap工具捕获Java进程的内存快照(Heap Dump),这是分析内存泄漏的基础数据。命令示例:jmap -dump:format=b,file=heapdump.hprof <Java进程ID>;也可在JVM启动参数中添加-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump,让JVM在发生OutOfMemoryError时自动生成堆转储。-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log),分析GC日志中的Full GC频率、持续时间和内存回收效果。若Full GC频繁且内存回收率低,可能提示存在内存泄漏。2. 修复代码中的常见泄漏场景
static HashMap)的生命周期与应用程序一致,若长期存储无用对象(如缓存未清理),会导致内存无法释放。解决方法是定期清理集合(如设置过期时间、使用WeakHashMap替代),或在不再需要时将集合置为null。try-with-resources语句或手动调用close()方法,会导致资源占用内存无法回收。解决方法是始终使用try-with-resources(Java 7+)确保资源自动关闭,例如:try (InputStream is = new FileInputStream("file.txt")) { // 业务逻辑 }。WeakReference)或软引用(SoftReference),或在不再需要时手动解除引用(如将对象置为null)。ThreadLocal变量存储在Thread对象中,若线程复用(如线程池)且未调用remove()方法,会导致对象长期驻留内存。解决方法是每次使用完ThreadLocal后调用remove()方法,避免内存泄漏。3. 优化JVM参数配置
-Xms)和最大大小(-Xmx),避免因堆内存不足导致频繁GC或内存溢出。例如:-Xms2g -Xmx4g(初始堆2GB,最大堆4GB)。-XX:+UseG1GC(启用G1GC)。-XX:NewRatio)、新生代中Eden区与Survivor区的比例(-XX:SurvivorRatio)。例如:-XX:NewRatio=2(新生代与老年代比例为1:2)、-XX:SurvivorRatio=8(Eden区与Survivor区比例为8:1:1)。4. 辅助工具与监控
top、htop、free -m等命令行工具实时监控系统内存使用情况,查看Java进程的内存占用趋势,判断是否存在内存泄漏。jconsole、jvisualvm或第三方工具(如Prometheus+Grafana、Arthas)监控JVM的内存、GC、线程等指标,及时发现内存泄漏的早期迹象。