目录
垃圾回收机制与内存泄漏
GC(garbage collection)的分类
GC判断策略
1.引用计数
2.可达性分析(解决循环依赖问题)
GC收集算法
1.复制算法
2.标记清除算法
3.标记整理算法
JVM所用gc判断策略
分代垃圾收集
JVM内存(堆里)
1.新生代
2.老生代
新生代与老生代所用gc收集算法
关于新生代与老生代的理解
三种算法比较
1.复制算法
2.标记清楚算法
3.标记整理算法
垃圾回收机制:主要是对内存的释放,因为在创建对象时要申请一个空间。
内存泄漏:内存一直被占着却不能使用。
System.gc(); //提醒JVM的垃圾回收执行GC,但是不确定是否马上执行GC
每个对象都有一个引用计数属性,新增一个引用时,计数加一,引用释放时,计数减一,引用计数为0时可以回收,此方法简单,无法解决循环依赖问题。
从GC根节点开始向下搜索,搜索走过的路径称为引用链。当一个对象到GC根节点没有任何引用链相连时则证明此对象是不可用的不可达对象。
将可用的内存按照容量分为大小相等的两块,每次只使用其中的一块,这一块内存用完时就将还存活的对象复制到另一块上面去,然后把已经用过的内存空间一次清理掉(如此循环往复)。
标记阶段:从根节点开始标记所有的可达对象,未被标记的为垃圾对象。
清除阶段:清除所有未被标记的对象
标记阶段:从根节点开始标记所有的可达对象,未被标记的为垃圾对象。
整理阶段:将所有存活的对象压缩到内存的一端,之后清理边界外的所有空间。
由于引用计数算法不能解决循环依赖问题,JVM并没有使用引用计数算法作为GC中判断对象是否存活的算法,用的是可达性分析。
java采用了分代垃圾收集,这种方法会跟java对象生命周期将堆内存划分为不同的区域,在垃圾收集过程中可能会将对象移到不同的区域。
新生代
区域 | 启用复制算法次数 |
伊甸园区 | 1 |
存活区 | 默认15次 |
老生代
一般情况下新建的对象均会被分配到伊甸园区(一些大对象特殊处理)这些对象经过第一次gc后,如果仍然存活将会被迁移到存活区,大对象直接进入老生代(大对象指的是需要大量连续内存空间的对象),这样做的目的是避免在伊甸园区和两个存活区之间发生大量的内存拷贝。
优点:简单高效
问题:
优点:速度较快
问题:容易产生内存碎片(主要原因:内存空间不连续)
优点:没有内存碎片
问题:效率不高