• 垃圾收集器与内存分配策略


    1. 引用计数GC算法

    每个对象都会有对应的计数器来计算对象引用,但JVM不会采用该策略,因为不能解决对象相互引用的回收。

    public class ReferenceCountingGC {
        
        public Object instance = null;
    
        private static final int _1M = 1024 * 1024;
        
        private byte[] bigSize = new byte[2 * _1M];
        
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            ReferenceCountingGC objA = new ReferenceCountingGC();
            ReferenceCountingGC objB = new ReferenceCountingGC();
            
            objA.instance = objB;
            objB.instance = objA;
            
            objA = null;
            objB = null;
            
            //GC
            System.gc();
        }
    
    }

    设置VM参数,打印GC日志

    -XX:+PrintGC
    -XX:+PrintGCDetails

    部分GC日志:

    [GC (System.gc()) [PSYoungGen: 6758K->584K(38400K)] 6758K->592K(125952K), 0.0015223 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
    [Full GC (System.gc()) [PSYoungGen: 584K->0K(38400K)] [ParOldGen: 8K->515K(87552K)] 592K->515K(125952K), [Metaspace: 2554K->2554K(1056768K)], 0.0048039 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

    可以从PSYoungGen中明显看到对象被回收,也就是JVM并没有采用引用计数算法。

    2. 可达性分析算法

     

    public class FinalizeEscapeGC {
    
        public static FinalizeEscapeGC instance = null;
        
        @Override
        protected void finalize() throws Throwable {
            // TODO Auto-generated method stub
            super.finalize();
            System.out.println("finalize() executed");
            FinalizeEscapeGC.instance = this;
        }
        
        
        public static void main(String[] args) throws InterruptedException {
            FinalizeEscapeGC.instance = new FinalizeEscapeGC();
            //在finalize()中拯救自己 - 成功
            instance = null;
            System.gc();
            //finalize()优先级很低,sleep
            Thread.sleep(500);
            if(instance != null) {
                System.out.println("still alive");
            }else {
                System.out.println("object recycling");
            }
            
            //再尝试自救 - 失败
            instance = null;        
            System.gc();
            Thread.sleep(500);
            if(instance != null) {
                System.out.println("still alive");
            } else {
                System.out.println("object recycling");
            }
        }
    } 

    在第一次GC时,finalize()第一次执行并将this赋予对象instance,因此this未被回收。但覆盖的finalize()仅执行一次,因此第二次GC时,对象被回收。

  • 相关阅读:
    比尔盖茨,乔布斯,扎克伯格,Linus 等巨佬的办公桌
    快速从 Windows 切换到 Linux 环境
    海外开发者账号上架总结
    Chrome 浏览器对标签进行整理和分组的功能太棒了!
    最受嵌入式软件工程师青睐的系统
    我最喜欢的云 IDE 有哪些?
    前端zip包下载
    el-upload上传组件(隐藏上传按钮/隐藏文件删除标记)
    滚动条样式
    使用ul标签制作简单的菜单(vue模板)
  • 原文地址:https://www.cnblogs.com/hello-yz/p/10488864.html
Copyright © 2020-2023  润新知