java垃圾回收

来源:互联网 发布:女装淘宝代理加盟 编辑:程序博客网 时间:2024/06/05 13:57

java内存一般认为有堆内存和栈内容,而堆内存中的对象实例是JVM回收的主要对象。

1.什么样的对象需要回收?

对于堆内存中已经没有任何用处(没有任何引用指向的对象)的对象就是可以被回收的对象。

2.怎么判断对象是“无用”的?

2.1 引用计数算法

基本思想:给对象添加一个引用计数器,每当有一个地方引用它,计数器就+1,当引用失效时,计数器值-1,任何时刻计数器值为0的对象就是不可能再被使用的。

问题:循环引用问题(父对象引用子对象,子对象也在引用父对象)。

2.2 可达性分析算法

基本思想:通过一系列的GC Roots对象作为起始点,从这些点出发向下搜索,所走过的路径成为引用链,当一个对象到GC Roots没有任何引用链相连,那么该对象是不可达的,也就是不能用的。

例如:


Object 1-4是可用的对象,Object 5-7虽然也存在引用,但是没有任何引用链和GC Roots相连,所以它们是不可达的。

3. 回收无用对象

哪些对象是无用的既然找到了,那么就可以回收了,注意,无用对象并不是立马就被回收,而是先将其加入到一个队列中,当下次发生GC的时候,这些对象仍旧没有被引用,那么才会被回收。

3.1 标记-清除算法

基本思想:将无用对象进行标记,标记完成后统一进行回收。

问题:产生空间碎片

3.2 复制算法

基本思想:将内存分成大小相等的两块,每次只用其中一块,(为了好叙述,把内存取名字为A、B)当这块内存满了之后(暂称为A内存),把内存中存活的对象复制到另外一块空闲的内存中(暂称为B内存),完全清除A内存,当B内存满了之后,将B内存中的存活对象复制到A中,完全清除B内存,以此类推。

问题:空间代价,每次有一半的内存被浪费。

3.3 标记-整理算法

基本思想:同标记-清除算法一样,先将内存中需要回收的对象进行标记,然后将内存中存活的对象向一端移动,清除边界之外的内存。

3.4 分代收集算法

基本思想:将内存分成新生代和老年代,根据各代特点进行清理。其中新生代分成Edon和两个大小相等的Survivor区(Survivor 0,Survivor 1),按比例8:1:1分配,每次只使用其中一个Survivor,该部分使用复制算法收集对象,但是不是按照1:1比例分配,而是8:1,因为新生代对象98$%具有“朝生夕死”的特点,将新建的对象放在Edon区,Edon满了之后,将触发一次Minor GC,将里面存活的对象复制到其中一个Survivor里,年龄+1,清除其他90%的内存,当新生代中的对象年龄达到了一定值,会转移到老年代,或者有大于Survivor内存的对象存在时,该部分对象也会进入老年代,此时老年代是作为新生代的“备用空间”。

老年代中的对象存活对象都比较高,所以不适合采用复制算法,可以选择标记-清除整理或者标记-整理算法。

补充:

Minor GC:普通GC,主要针对新生代的GC

Major GC、Full GC:全局GC,针对老年代的GC,偶尔会清理新生代和永久代对象。

对于垃圾回收,可说的差不多就这么多吧,附上我的学习笔记,大家共勉~

垃圾回收机制