代码改变世界

Java中的GC

2018-08-15 10:16  摘花  阅读(213)  评论(0编辑  收藏  举报

在梳理之前,要清晰的三个目标:

1,什么对象需要回收?

2,什么时候回收?

3,怎么回收?

问题1,当然是这个对象再也用不上的时候啦!就像从邻居家借了一把锄头,活没干完之前就还回去岂不是很傻,因为要用的时候又要去借。那怎么知道活有没有干完呢?

一,引用计数器,每当一个地方引用此对象,就给计数器加一,当引用为0时,说明这个对象已经被抛弃了,大家都用完了她(坏笑)。但是虚拟机并不是这么做的(JVM:我是很正派的)。

二,可达性分析,从一个根节点出发,如果一个对象不在这棵树上,这个对象就是应该回收的,就像一棵自然界的树,树上的叶子掉了,即使叶子曾经是树的一部分,但是现在叶子已经脱离树这个大环境了,我们就把它扫进垃圾堆。

可以作为根节点(我的理解是对象本身稳定存在的、不容易被回收的)

A)虚拟机栈中引用的对象

B)方法区中静态属性以及常量引用的对象

C)Native方法引用的对象

Java对象的引用在JDK1.2之后分为四个级别(依次递减)强(基本不会被回收)、软(内存不足时才会被回收)、弱(下一次GC发生时被回收)、虚(基本已经推上断头台,死了通知我一下就好)

而finalize()方法则是扮演古装戏的“刀下留人!”,当然救人的成功率不是100%。

 

回收的算法:

1,标记清除(mark-sweep):第一遍标记要回收的对象,第二遍杀掉,效率不高还产生碎片

2,复制算法(copying):把内存两分,把存货的对象复制到另一块上去,浪费内存。

3,标记整理:把存活的对象移动到一端,然后清理掉边界以外的内存

4,分代收集:新生代,存活率低,直接采用复制算法,老年代存活率高,使用标记清除或者标记整理。