美文网首页
垃圾收集算法

垃圾收集算法

作者: T_log | 来源:发表于2018-07-18 16:42 被阅读9次

垃圾收集算法

  1. 在Java内存中,不停的有对象的创建与消亡,在内存一定的情况下,内存的动态分配和垃圾收集都由JVM去帮我们程序员自动完成,那么,JVM在内存回收时的疑问如下

哪些内存需要被回收
什么时候回收
如何回收

  1. 对象已经死了吗?

java对象几乎全部存放在堆中,垃圾收集的主要区域也是Java堆内存。在垃圾收集器进行垃圾收集时,首先要确定哪些对象还存活,不需要回收,哪些对象已经死去,需要被回收。

  1. 引用计数算法

给每个对象一个引用计数器,每当有一个地方引用它时,计数器的值就加一,当引用失效时,计数器的值就减1,任何时刻计数器的值为0的对象,代表不可能在被利用。
引用计数器的优缺点

  1. 实现简单,判断效率高
  2. 难以解决对象之间相互引用的问题
package com.schoki.jvm.chapter2;
/**
 * @author : jzb219@gmial.com
 * @description : 测试 objA objB是否会被回收
 * @date : 2018/7/18 下午3:42
 */
public class ReferenceCountingGC {

    public Object instance = null;

    private static final int _1M = 1024 * 1024;

    /**
     * 该变量的意义在于占点内存,以便在垃圾收集时,可以看到GC日志中,是否会回收
     */
    private byte[] bigSize = new byte[2 * _1M];

    public static void main(String[] args) {
        ReferenceCountingGC objA = new ReferenceCountingGC();
        ReferenceCountingGC objB = new ReferenceCountingGC();
        objA.instance = objB;
        objB.instance = objA;

        objA = null;
        objB = null;


        //假设发生GC, objA objB是否会被回收
        System.gc();
    }
}

运行结果(JDK1.8)

[GC (System.gc()) [PSYoungGen: 6779K->576K(38400K)] 6779K->584K(125952K), 0.0016589 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 576K->0K(38400K)] [ParOldGen: 8K->509K(87552K)] 584K->509K(125952K), [Metaspace: 3286K->3286K(1056768K)], 0.0075244 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
 PSYoungGen      total 38400K, used 333K [0x0000000795580000, 0x0000000798000000, 0x00000007c0000000)
  eden space 33280K, 1% used [0x0000000795580000,0x00000007955d34a8,0x0000000797600000)
  from space 5120K, 0% used [0x0000000797600000,0x0000000797600000,0x0000000797b00000)
  to   space 5120K, 0% used [0x0000000797b00000,0x0000000797b00000,0x0000000798000000)
 ParOldGen       total 87552K, used 509K [0x0000000740000000, 0x0000000745580000, 0x0000000795580000)
  object space 87552K, 0% used [0x0000000740000000,0x000000074007f690,0x0000000745580000)
 Metaspace       used 3292K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 363K, capacity 388K, committed 512K, reserved 1048576K

从运行结果可以看到

  1. 第一行中PSYoungGen ,说明收集器采用的是Parallel Scavenge收集器
  2. 6779K->576K(38400K),回收前是6779K,回收后576K,说明虽然objA和objB存在相互引用,但是依然会被垃圾收集器回收掉,从侧面也说明垃圾收集算法采用的不是引用计数算法
  1. 可达性分析算法

通过一些列(注意是很多哦,我特么刚开始以为一个应用里面就一个GC Roots)的成为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径成为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时(或者说GC Roots到这个对象不可达),则说明这个对象是不可用的
哪些对象可以作为GC Roots

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象--代表应用上下文
  2. 方法区中类静态属性引用的对象
  3. 方法区中,常量引用的对象
  4. 本地方法栈中JNI(一般说native方法)引用的对象(注:这个没太搞明白)

参考
周志明《深入理解Java虚拟机》

写在最后

做一个灵魂和肉体分离的人,灵魂不受肉体的束缚,灵魂可以指挥肉体

相关文章

  • 第三章(二)GC

    本篇主要讲 垃圾收集算法 、 HotSpot的的算法实现 和 垃圾收集器。 垃圾收集算法 标记-清除算法 Mark...

  • JVM垃圾回收

    GC垃圾回收流程 垃圾收集算法 垃圾回收算法 引用类型 垃圾回收的时机 1.垃圾收集算法 (1).引用计数算法含义...

  • 4种垃圾收集算法及8种垃圾收集器

    文主要介绍4种垃圾收集算法及8种垃圾收集器: 垃圾收集算法 1、标记-清除算法(Mark-Sweep) “标记-清...

  • JVM学习笔记四【垃圾收集器】

    前文我们针对垃圾收集的区域,垃圾收集的对象,垃圾收集算法进行了介绍;而垃圾收集器就是收集算法的实现,如下是HotS...

  • JVM第四天-垃圾收集器

    一、垃圾收集器概述 垃圾收集器是垃圾回收算法(标记-清除算法、复制算法、标记-整理算法、火车算法)的具体实现,不同...

  • JVM:这是一份全面 & 详细的 (GC)垃圾收集算法

    前言 不同的内存区域采用不同的垃圾收集算法 而不同垃圾收集算法决定了垃圾收集的效率 & 效果 本文将全面讲解垃圾收...

  • Jvm之CMS垃圾收集器

      这篇文章主要介绍JVM的CMS垃圾收集器,以及JVM提供的垃圾收集算法。 一、垃圾收集算法   JVM提供的三...

  • JVM堆的分配和回收

    1. 内存分配 现代收集器基本都采用分代收集算法 1.1 概述 垃圾收集 垃圾回收 垃圾收集器 GC 算法是内存回...

  • Java虚拟机垃圾收集算法实现

    垃圾收集算法实现 垃圾收集算法实现必须考虑运行效率。 对象存活判定算法实现 对象存活判定算法都使用可达性分析算法实...

  • 垃圾收集

    垃圾收集算法 标记清除法:循环应用 引用计数法:空间碎片 复制算法:新生代使用该算法进行垃圾收集 标记压缩算法:老...

网友评论

      本文标题:垃圾收集算法

      本文链接:https://www.haomeiwen.com/subject/ggiipftx.html