一 什么是内存泄漏
可达性分析算法来判断对象是否是不再使用的对象,本质都是判断一个对象是否被引用。那么对于这种情况下,由于代码的实现不同就会出现多种内存泄漏问题(让 JVM 误以为此对象还在引用中,无法回收,造成内存泄漏)
内存泄漏理解见下表。
是否还被使用? | 是 | 是 |
是否还被需要? | 是 | 否 |
是内存泄漏吗? | 不是内存泄漏 | 是内存泄漏 |
二 内存泄漏理解
严格来说,只有对象不会再被程序使用,但是 GC 又不能回收它们,才叫内存泄漏。
但实际上很多时候一些不太友好的实践(或疏忽)会导致对象的生命周期很长甚至导致OOM,也可以叫做宽泛意义上的"内存泄漏"。
对象 X 引用对象 Y,X 的生命周期比 Y 生命周期长。
那么当 Y 生命周期结束时,X 依然引用着 Y,这时候,垃圾回收器是不会回收对象 Y 的。
如果对象 X 还引用着生命周期比较短的 A、B、C,对象 A 又引用着对象 a、b、c,这样就可能造成大量无用对象不能被回收,进而占据着内存资源,造成内存泄漏,直到内存溢出。
三 内存泄漏与内存溢出的关系
1 内存泄漏
申请了内存用完了不释放,比如一共有1024M的内存,分配了 512 的内存一直不回收,那么可以用的内存只有 512M 了,仿佛泄漏掉了一部分。
通俗一点讲,内存泄漏就是占着茅坑不走。
2 内存溢出
申请内存时,没有足够的内存可以使用。
通俗一点讲,一个厕所三个坑,有两个占着茅坑不走的(内存泄漏),剩下最后一个坑,厕所接待压力很大,此时来了两个人,坑位(内存)不够了,内存泄漏变成了内存溢出。
可见,内存泄漏和内存溢出的关系:内存泄漏的增多,最终会导致内存溢出。
四 泄漏分类
-
经常发生:发生内存泄漏的代码很多次被执行,每次执行,泄漏一块内存。
-
偶然发生:在某些特定情况下才会发生。
-
一次性:发生内存泄漏的方法只会执行一次。
-
隐式泄漏:一直占着内存不释放,直到执行结束;严格说这个不算内存泄漏,因为最终释放掉了,但是如果执行时间特别长,也可能会导致内存耗尽。