内存溢出(OOM),指程序申请内存时,没有足够的内存供申请者使用,此时就会报错OOM,即所谓的内存溢出。
内存泄漏(Memory Leak),指程序在申请内存后,内存无法被JVM/操作系统回收的现象。内存泄漏累积到一定程度之后会导致内存溢出。
造成内存溢出的原因有很多种,比如:
1.启动参数内存值设定的过小;
2.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
3.代码中存在死循环或循环产生过多重复的对象实体;
4.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收(内存泄漏);
针对上述1~3条原因,平常保持良好的编码习惯以及采取一定的措施,一般来说可以很好的规避,比如:
1、修改JVM启动参数,直接增加内存;(-Xms,-Xmx参数)
2、避免一次性查询全部记录或者过多记录,最好采取分页的形式查询
3、在编码过程中尽量避免写死循环或递归调用,除非业务需要,也要做到心知肚明
针对第4点,其实从代码上我们可以做一些相关的检查,比如检查List、Map等集合对象是否有未及时清除的问题,因为List、Map等集合中会始终存有对对象的引用,使得这些对象不能被GC回收;但往往实际情况是:代码中使用List、Map的地方太多,没办法逐一排查,或者是做了排查但有遗漏;甚至还有工期紧、上线急、没时间去排查代码或者是当局者迷无法自我发现等等各种原因,总之检查代码的方式很难做到完全规避内存泄漏的问题。
那么有没有什么好的办法能够把第4点的问题完全规避呢?答案是:没有。即使你在上线前做了充分的性能和压力测试,也不一定能完全暴露问题。所以,带着问题上线不可避免,这也是业界的一个常态。
关键是有没有什么好的方式可以及时发现线上环境存在的内存泄漏问题,以及及时定位到问题代码呢,这将是我后面2篇文章要讲的内容,请大家敬请期待~
以上为个人的一些思考与总结,难免会有纰漏,如有不足之处,欢迎指正!
网友评论