1 内存溢出和内存泄漏
- 概念:内存泄漏:在Java中如果不在使用一个对象,但是该对象依然在GC ROOT的引用链上,这个对象就不会被垃圾回收器回收,这种情况就称之为内存泄漏。
- 内存泄漏绝大多数情况都是由堆内存泄漏引起的,所以后续没特殊说明讨论的均为堆内存泄漏。
- 若持续发生内存泄漏,不管有多大的内存迟早会被消耗完,最终导致的结果就是内存溢出。但是产生内存溢出并不是只有内存泄漏这一种原因。
- 内存溢出指的是内存的使用量超过了Java虚拟机可以分配的上限,最终产生了内存溢出OutOfMemory的错误。
- 常见场景:定时任务;大量请求同时处理产生的数据未及时清理等。
2 解决内存溢出的方法
- 解决思路
- 发现问题:通过监控工具尽可能早地发现内存慢慢变大的现象;
-
- top命令:top命令是linux下用来查看系统信息的命令;
- VisualVM:它是多功能合一的Java故障排除工具并且是一款可视化工具,整合了命令行JDK工具和轻量级分析功能。下载地址:https://visualvm.github.io/
- Prometheus + Grafana 是企业常用的监控方案;
- 诊断原因
-
- 生成内存快照并分析;
- 在线定位问题。
- 修复问题
- 测试验证
- 产生内存溢出的原因:
- 代码中的内存泄漏:equals() 和 hashCode();内部类引用外部类;ThreadLocal的使用;String的intern方法;通过静态字段保存对象;资源没有争创关闭;
- 并发请求问题;并发请求问题指的是用户通过发送请求向Java应用获取数据,正常情况下Java应用将数据返回之后,这部分数据就可以在内存中被释放掉;