引用计数算法

1、概念

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

引用计数方法实现简单、判定效率也很高、在大部分情况下它是一个不错的算法,例如COM、Python、游戏脚本中都被广泛应用。但是在主流的JAVA虚拟机里面没有选用引用计数算法主要的原因是它很难解决对象之间相互循环引用的问题。

2、验证

虚拟机参数配置

-verbose:gc

-XX:+PrintGCDetails

package com.base.dev.baisc.gc;

/**
 *  @author: zhaoyihang
 *  @Date: 2022/6/8 11:36 上午
 *  @Description:
 */
public class ReferenceCountingGC {

    public Object instance = null;
    private static final int _1MB = 1024 * 1024;

    private byte[] bigSize = new byte[2 * _1MB];

    public static void testGC(){
        ReferenceCountingGC A = new ReferenceCountingGC();
        ReferenceCountingGC B = new ReferenceCountingGC();

        A.instance = B;
        B.instance = A;

        A = null;
        B = null;

        System.gc();
    }

    public static void main(String[] args) {
        testGC();
    }
}


/Library/Java/JavaVirtualMachines/jdk-11.0.7.jdk/Contents/Home/bin/java -verbose:gc -XX:+PrintGCDetails "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60505:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Users/zhaoyihang/soft/51shebao/base-parent/baisc-java/target/classes:/Users/zhaoyihang/.m2/repository/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar:/Users/zhaoyihang/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/Users/zhaoyihang/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/Users/zhaoyihang/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/Users/zhaoyihang/.m2/repository/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar:/Users/zhaoyihang/.m2/repository/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar:/Users/zhaoyihang/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot-starter-web/2.2.5.RELEASE/spring-boot-starter-web-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot-starter/2.2.5.RELEASE/spring-boot-starter-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.2.5.RELEASE/spring-boot-starter-logging-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/Users/zhaoyihang/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/Users/zhaoyihang/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.12.1/log4j-to-slf4j-2.12.1.jar:/Users/zhaoyihang/.m2/repository/org/apache/logging/log4j/log4j-api/2.12.1/log4j-api-2.12.1.jar:/Users/zhaoyihang/.m2/repository/org/slf4j/jul-to-slf4j/1.7.30/jul-to-slf4j-1.7.30.jar:/Users/zhaoyihang/.m2/repository/jakarta/annotation/jakarta.annotation-api/1.3.5/jakarta.annotation-api-1.3.5.jar:/Users/zhaoyihang/.m2/repository/org/yaml/snakeyaml/1.25/snakeyaml-1.25.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot-starter-json/2.2.5.RELEASE/spring-boot-starter-json-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.10.2/jackson-databind-2.10.2.jar:/Users/zhaoyihang/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.10.2/jackson-annotations-2.10.2.jar:/Users/zhaoyihang/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.10.2/jackson-core-2.10.2.jar:/Users/zhaoyihang/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.10.2/jackson-datatype-jdk8-2.10.2.jar:/Users/zhaoyihang/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.10.2/jackson-datatype-jsr310-2.10.2.jar:/Users/zhaoyihang/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.10.2/jackson-module-parameter-names-2.10.2.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/2.2.5.RELEASE/spring-boot-starter-tomcat-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.31/tomcat-embed-core-9.0.31.jar:/Users/zhaoyihang/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/9.0.31/tomcat-embed-el-9.0.31.jar:/Users/zhaoyihang/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.31/tomcat-embed-websocket-9.0.31.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot-starter-validation/2.2.5.RELEASE/spring-boot-starter-validation-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2.jar:/Users/zhaoyihang/.m2/repository/org/hibernate/validator/hibernate-validator/6.0.18.Final/hibernate-validator-6.0.18.Final.jar:/Users/zhaoyihang/.m2/repository/org/jboss/logging/jboss-logging/3.4.1.Final/jboss-logging-3.4.1.Final.jar:/Users/zhaoyihang/.m2/repository/com/fasterxml/classmate/1.5.1/classmate-1.5.1.jar:/Users/zhaoyihang/.m2/repository/org/springframework/spring-web/5.2.4.RELEASE/spring-web-5.2.4.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/spring-beans/5.2.4.RELEASE/spring-beans-5.2.4.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/spring-webmvc/5.2.4.RELEASE/spring-webmvc-5.2.4.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/spring-aop/5.2.4.RELEASE/spring-aop-5.2.4.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/spring-context/5.2.4.RELEASE/spring-context-5.2.4.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/spring-expression/5.2.4.RELEASE/spring-expression-5.2.4.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar:/Users/zhaoyihang/.m2/repository/org/springframework/spring-core/5.2.4.RELEASE/spring-core-5.2.4.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/spring-jcl/5.2.4.RELEASE/spring-jcl-5.2.4.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot-devtools/2.2.5.RELEASE/spring-boot-devtools-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot/2.2.5.RELEASE/spring-boot-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.2.5.RELEASE/spring-boot-autoconfigure-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/springframework/boot/spring-boot-configuration-processor/2.2.5.RELEASE/spring-boot-configuration-processor-2.2.5.RELEASE.jar:/Users/zhaoyihang/.m2/repository/org/projectlombok/lombok/1.18.2/lombok-1.18.2.jar:/Users/zhaoyihang/.m2/repository/com/alibaba/fastjson/1.2.73/fastjson-1.2.73.jar com.base.dev.baisc.gc.ReferenceCountingGC
[0.006s][warning][gc] -XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.
[0.024s][info   ][gc,heap] Heap region size: 1M
[0.032s][info   ][gc     ] Using G1
[0.032s][info   ][gc,heap,coops] Heap address: 0x0000000700000000, size: 4096 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
[0.617s][info   ][gc,task      ] GC(0) Using 4 workers of 4 for full compaction
[0.617s][info   ][gc,start     ] GC(0) Pause Full (System.gc())
[0.617s][info   ][gc,phases,start] GC(0) Phase 1: Mark live objects
[0.620s][info   ][gc,stringtable ] GC(0) Cleaned string and symbol table, strings: 2658 processed, 9 removed, symbols: 26074 processed, 0 removed
[0.620s][info   ][gc,phases      ] GC(0) Phase 1: Mark live objects 2.917ms
[0.620s][info   ][gc,phases,start] GC(0) Phase 2: Prepare for compaction
[0.621s][info   ][gc,phases      ] GC(0) Phase 2: Prepare for compaction 0.684ms
[0.621s][info   ][gc,phases,start] GC(0) Phase 3: Adjust pointers
[0.621s][info   ][gc,phases      ] GC(0) Phase 3: Adjust pointers 0.910ms
[0.622s][info   ][gc,phases,start] GC(0) Phase 4: Compact heap
[0.623s][info   ][gc,phases      ] GC(0) Phase 4: Compact heap 1.119ms
[0.626s][info   ][gc,heap        ] GC(0) Eden regions: 5->0(4)
[0.626s][info   ][gc,heap        ] GC(0) Survivor regions: 0->0(0)
[0.626s][info   ][gc,heap        ] GC(0) Old regions: 0->4
[0.626s][info   ][gc,heap        ] GC(0) Humongous regions: 6->0
[0.626s][info   ][gc,metaspace   ] GC(0) Metaspace: 6303K->6303K(1056768K)
[0.626s][info   ][gc             ] GC(0) Pause Full (System.gc()) 10M->2M(14M) 9.129ms
[0.626s][info   ][gc,cpu         ] GC(0) User=0.01s Sys=0.01s Real=0.01s
[0.627s][info   ][gc,heap,exit   ] Heap
[0.627s][info   ][gc,heap,exit   ]  garbage-first heap   total 14336K, used 2810K [0x0000000700000000, 0x0000000800000000)
[0.627s][info   ][gc,heap,exit   ]   region size 1024K, 1 young (1024K), 0 survivors (0K)
[0.627s][info   ][gc,heap,exit   ]  Metaspace       used 6337K, capacity 6379K, committed 6528K, reserved 1056768K
[0.627s][info   ][gc,heap,exit   ]   class space    used 550K, capacity 570K, committed 640K, reserved 1048576K

Process finished with exit code 0

3、结论

  代码中A和B都包含了字段instance,A.instance=B B.instance=A除此之外两个对象无任何引用,实际上这两个对象已经不可能在被访问,但是因为他们互相引用对方,导致它们引用计数器都不为0,于是引用计数算法无法通知GC收集器回收他们。

但是根据代码运行结果来看

 它们被回收了,意味这虚拟已并没有因为两个对象互相引用不回收它们,也证明了虚拟机并不是通过引用计算算法来判定对象是否存活的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值