Java内存溢出和泄漏的排查

什么样的人才会接触到这样的问题呢?

  一定是有一个项目在跑着,然后突然变慢了,你才会想到排查内存泄露的问题的。作为小白,写写逻辑,我觉得基本上接触不到这个问题。自己写程序报错OOM,那需要很大的代码错误。

我接触到这个问题是上次项目经理面试,问到我了,虽然我也是结合虚拟机答的,但是感觉回答的不是很好,所以自己想将这个问题整明白。

~PS:原文真的写的好,点击去看看把,尊重原创,这里放链接。

 然后我自己做个总结,当别人要和你聊这个问题的时候,你应该怎么聊:

内存溢出和内存泄露分别是什么 

  首先内存溢出和内存泄露不是一个东西,但是他们又有关系:内存溢出是只有500毫升的杯子想装501毫升的水,可想而知肯定是不行的。内存泄露是对象即使不用,也保留着引用,因此无法得到回收,所以一直占用着内存空间。所以他们的关系是:经常性的内存泄露会导致内存溢出。内存溢出相当于是非要在原来500毫升的水杯里放一块石头,结果水杯连500毫升的水也放不了了。

 知道内存是什么了,还应该知道内存泄露的原因

  我在这里默认你已经学习过一些JVM的内容,特别是GC。我们知道对象一般是从年轻代开始的(除了一定规模的大对象,直接放到老年代),然后经历了一次又一次的垃圾回收(次数是可以设置的默认15),幸存到一定次数以后,就可以被安排到老年代了,因为老年代GC相比较少。说到垃圾回收机制,不得不提判断是垃圾的算法,从GCroot只要可达对象,也就是说保留对象的引用,就不是垃圾,就不会回收。问题就出在这里,就是因为不正当的对象的引用,所以那些因为编程错误的原因,导致大量的对象到了老年区,本来老年区是应该比较安静的,现在来了这么一波本来不该属于老年区的东西。老年区也变得热闹起来(老年代的GC变得频繁)。所以你这才发现了内存泄露的问题。GC是需要花时间的,并且程序需要等待。

  这部分总结一句话:内存泄露就是对象在使用完以后不能及时被清理,熬过了一次又一次的回收,都到的老年区去了。

 发现内存泄露与精准定位内存泄露

 就像能够表名感冒的流鼻涕和咳嗽一样,能够给内存泄露提示的是程序变慢。上边也提到过了,GC是花时间的,并且,在GC时候,程序是需要停下来等待的,于是程序就是这样变慢的。因此我们也有了定位内存泄露的切入点,那就是监控老年代的GC情况,找出异常存在的对象,需要靠我们自己判断,那些不行该出现在这里。

  因为这仅仅是一个下总结,所以,我不写具体的定位排查到具体代码的方案,上边给了一个连接,原文写的非常清楚。感兴趣的可以进去看看。

容易发生内存泄露的典例

 

猜你喜欢

转载自blog.csdn.net/star1210644725/article/details/92803973
今日推荐