java面试-什么是GC root_byte [] no gc root-程序员宅基地

技术标签: jvm  

哪些对象可以作为 GC Roots 的对象:

  • 虚拟机栈中局部变量(也叫局部变量表)中引用的对象
  • 方法区中类的静态变量、常量引用的对象
  • 本地方法栈中 JNI (Native方法)引用的对象 
public class GCRootDemo {
    private byte[] byteArray = new byte[100 * 1024 * 1024];
 
    private static GCRootDemo gc2;
    private static final GCRootDemo gc3 = new GCRootDemo();
 
    public static void m1(){
        GCRootDemo gc1 = new GCRootDemo();
        System.gc();
        System.out.println("第一次GC完成");
    }
    public static void main(String[] args) {
        m1();
    }
}  

 

解释:

gc1:是虚拟机栈中的局部变量

gc2:是方法区中类的静态变量

gc3:是方法区中的常量

都可以作为GC Roots 的对象。

root大概有这些
所有Java线程当前活跃的栈帧里指向GC堆里的对象的引用;换句话说,当前所有正在被调用的方法的引用类型的参数/局部变量/临时值。
VM的一些静态数据结构里指向GC堆里的对象的引用,例如说HotSpot VM里的Universe里有很多这样的引用。
JNI handles,包括global handles和local handles(看情况)
所有当前被加载的Java类(看情况)
Java类的引用类型静态变量(看情况)
Java类的运行时常量池里的引用类型常量(String或Class类型)(看情况)
String常量池(StringTable)里的引用

所有Java线程当前活跃的栈帧,静态引用等指向GC堆里的对象的引用;换句话说,当前所有正在被调用的方法的引用类型的参数/局部变量/临时值。

假设hashMap 在扩容的时候,正巧发生了gc,在标记阶段,要找出所有的root,这里的 oldTab 就是root,通过这个root,然后遍历他的所有属性,如果它里面的内容不为null 我们继续遍历内容里的对象字段是否为null,标记出所有不为null的节点。继续下图,子节点

静态引用这样的代码也会成为root

private static Object objoct;

 

这里可以看到Node里还有Node,标记的时候就这这样,遍历每个属性的子属性,一直到遍历完,则这些被标记的为有引用的。gc标记的过程就是一棵树在遍历他所有的节点,这样应该很清楚了吧。最后没有被标记的就给清楚掉。

/**
 * @author 铁拳阿牛
 * @createTime 2018/7/14 下午3:33
 **/
public class Node {

    private Object object;
       //如果这个Node被引用他的属性又被引用,属性为对象且不为null,这样一直遍历下去,
     
    private Node node;
}

 

理论扯完了,接下来实践

/**
 * @author 铁拳阿牛
 * @createTime 2018/7/14 下午3:46
 *
 * 请把以下参数设置到jvm里
 * -Xmx4000M -Xms4000M -Xmn1300M  -XX:+UseParNewGC  -XX:+UseConcMarkSweepGC  -XX:+UseCMSInitiatingOccupancyOnly  -XX:CMSInitiatingOccupancyFraction=75 -XX:+PrintGCDetails
 **/
public class Test {

    private static final int _1MB = 1024 * 1024;

    private static final int LENGTH = 40000000;

    public static void main(String[] args) {
        Node next = null;
        for(int i = 0; i <= LENGTH; i++){
            Node node = new Node(i,next);
            next = node;
        }
        //如果不设置为null这里将会又大批量的遍历,打开这里和不打开这里,gc时间完全不一样,现在你直到为什么要设置为null了吗?
//        next = null;
        triggerGC();
    }

    /**
     * 不触发gc看不见效果
     * new 很多小对象。不然直接到 old区去了。
     */
    private static void triggerGC(){
//        byte[] all = new byte[2000 * _1MB]; //这里为什么没又直接new 一个大对象?它可能直接就到old区去了。
        for(int i = 0 ; i < 500 ; i++){
            byte[] bytes = new byte[2 * _1MB];
        }
    }

    //POJO 不用看这里
    static class Node {
        
        private int valuel;
        
        private Node node;
        
        public Node(int valuel, Node node) {
            this.valuel = valuel;
            this.node = node;
        }

        public int getValuel() {
            return valuel;
        }

        public void setValuel(int valuel) {
            this.valuel = valuel;
        }

        public Node getNode() {
            return node;
        }

        public void setNode(Node node) {
            this.node = node;
        }
    }

}

第一次我们要把eden 的空间尽可能的占满将这两行代码注释掉,发现eden已经用了94% 很不错。

//        next = null;
//        triggerGC();
~~~~~~~~~~~~~~~~~
Heap
 par new generation   total 1198080K, used 1001063K [0x00000006c6000000, 0x0000000717400000, 0x0000000717400000)
  eden space 1064960K,  94% used [0x00000006c6000000, 0x0000000703199e78, 0x0000000707000000)
  from space 133120K,   0% used [0x0000000707000000, 0x0000000707000000, 0x000000070f200000)
  to   space 133120K,   0% used [0x000000070f200000, 0x000000070f200000, 0x0000000717400000)
 concurrent mark-sweep generation total 2764800K, used 0K [0x0000000717400000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 2674K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

然后我们开始测试了,发现gc时间非常的短, [Times: user=0.04 sys=0.00, real=0.01 secs] ,gc基本没有占用我们的时间。

        next = null;
        triggerGC();
~~~~~~~~~~~~~~~~~
[GC (Allocation Failure) [ParNew: 1063732K->399K(1198080K), 0.0101658 secs] 1063732K->399K(3962880K), 0.0102629 secs] [Times: user=0.04 sys=0.00, real=0.01 secs] 
Heap
 par new generation   total 1198080K, used 933048K [0x00000006c6000000, 0x0000000717400000, 0x0000000717400000)
  eden space 1064960K,  87% used [0x00000006c6000000, 0x00000006feeca630, 0x0000000707000000)
  from space 133120K,   0% used [0x000000070f200000, 0x000000070f263d38, 0x0000000717400000)
  to   space 133120K,   0% used [0x0000000707000000, 0x0000000707000000, 0x000000070f200000)
 concurrent mark-sweep generation total 2764800K, used 0K [0x0000000717400000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 2674K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

然后我们对比测试,发现gc时间非常的短,[Times: user=145.85 sys=1.89, real=20.17 secs] ,额这个gc时间。。。

//        next = null;
        triggerGC();
~~~~~~~~~~~~~~~~~
[GC (Allocation Failure) [ParNew: 1063732K->133119K(1198080K), 20.1710025 secs] 1063732K->938404K(3962880K), 20.1710585 secs] [Times: user=145.85 sys=1.89, real=20.17 secs] 
Heap
 par new generation   total 1198080K, used 1065769K [0x00000006c6000000, 0x0000000717400000, 0x0000000717400000)
  eden space 1064960K,  87% used [0x00000006c6000000, 0x00000006feeca630, 0x0000000707000000)
  from space 133120K,  99% used [0x000000070f200000, 0x00000007173ffff8, 0x0000000717400000)
  to   space 133120K,   0% used [0x0000000707000000, 0x0000000707000000, 0x000000070f200000)
 concurrent mark-sweep generation total 2764800K, used 805284K [0x0000000717400000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 2676K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

把这些对象标记后其他的都是要清除的,所以现在知道为什么要设置为null
了吗?就是为了加快标记阶段。如果你有个超大的map或者list的时候这样
做会有一点点帮助。(普通开发过程中基本没有必要考虑)

 

 

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/luzhensmart/article/details/105883145

智能推荐

程序员应该用程序来思维,有空来研究一下狼 羊 草和农夫过河,将算法转换为代码《转》_java 状态空间 农夫狼羊白菜-程序员宅基地

文章浏览阅读4k次。题目描述:农夫需要把狼、羊、菜和自己运到河对岸去,只有农夫能够划船,而且船比较小,除农夫之外每次只能运一种东西,还有一个棘手问题,就是如果没有农夫看着,羊会偷吃菜,狼会吃羊。请考虑一种方法,让农夫能够安全地安排这些东西和他自己过河。 这个题目考察人的快速逻辑运算和短期记忆力。分析一下,在狼-》羊-》菜这个食物链条中,“羊”处在关键位置,解决问题的指导思想就是将“羊”与“狼”_java 状态空间 农夫狼羊白菜

经验总结:java软件下载安装-程序员宅基地

文章浏览阅读59次。开头在找工作的过程中,对于 Redis 技术知识的掌握已经成为必须的技能。美团面试常常就会被问到Redis相关知识,而这次我就差点倒在了美团3面,面试官连问我以下几个Redis的问题,然后就卡壳了…redis了解吗?你说说怎么用redis实现分布式锁?Redis常用数据结构及底层数据结构实现如何解决 Redis 的并发竞争 Key 问题如何保证缓存与数据库双写时的数据一致性?剩下的不太记得了…为此面试完回来针Redis专门做了一个面试问题大总结01 Java技术概览0

单片机扩展IO口-程序员宅基地

文章浏览阅读3.3k次。单片机如何扩展IO口?首先我们先讲讲为什么要扩展IO口。在我们使用51单片机的时候,有时候会出现IO口不够用的情况。比如键盘!这个时候IO口的资源就十分有限了。按键是我们常用的器件,做某些东西的时候又不能缺少按键。如果一个按键对应一个IO口,那么可想而知,按键所占的IO口的数量是很大的。单片机IO口的资源是有限的,因此我们要采取一些方法来扩展单片机的IO口,控制按键所占的单片机IO_单片机扩展io口

python取array中指定元素_python取数组中的指定元素-程序员宅基地

文章浏览阅读3.5w次,点赞7次,收藏29次。对于array,如2-D的array,如何取指定元素设array为3*10的shapes = array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])想取..._python取数组中的指定元素

应用软件安装_launch manager ultimate-程序员宅基地

文章浏览阅读905次。在进行开发中,会使用到很多各种类型的软件,现在将其进行整理,列表如下,如有需要,请给我留言,我可以给分享给大家。001_application software 序号 名称 备注 1 极速PDF.7z PDF查看器 2 鲁大师.7z 硬件检测工具 3 金山打字通.7z 打字练习 4 ..._launch manager ultimate

[Windows]_[初级]_[Release程序的崩溃报告minidump解决方案]_minidump 格式的崩溃报告-程序员宅基地

文章浏览阅读3.9k次。场景:1. Release的程序崩溃时,崩溃报告可以让开发人员查明代码哪里出了问题,用处大大的。2. 只有用VS的编译器才支持,所以MinGW就无缘了。3. 使用了未处理异常过滤处理函数._minidump 格式的崩溃报告

随便推点

matlab 将数组写入txt_matlab定义一维数组 输出到文本文件中的数据-程序员宅基地

文章浏览阅读8.4k次。fid = fopen('100data.txt','w');fprintf(fid,'%d\n',a); % a 为要写入的数组 fclose(fid)_matlab定义一维数组 输出到文本文件中的数据

matlab安装打不开(一个黑框一闪而过)解决办法!_matlab打不开-程序员宅基地

文章浏览阅读1.9w次,点赞23次,收藏93次。matlab安装打不开(一个黑框一闪而过)解决办法_matlab打不开

学习材料1-程序员宅基地

文章浏览阅读144次。【五脏】心、肝、脾、肺、肾【六腑】胃、胆、三焦、膀胱、大肠、小肠【七情】喜、怒、哀、乐、爱、恶、欲【五常】仁、义、礼、智、信【五伦】君臣、父子、兄弟、夫妇、朋友【三姑】尼姑、道姑、卦姑【六婆】牙婆、媒婆、师婆、虔婆、药婆、稳婆【九属】玄孙、曾孙、孙、子、身、父、祖父、曾祖父、高祖父【五谷】稻、黍、稷、麦、豆【中国八大菜系】四川菜、湖南菜、山东菜、江苏菜、浙江菜、广东菜、福建菜、安徽菜【五毒】石胆、...

Keras实现CNN:手写数字识别准确率99.6%_cnn 手写数字识别 99正确率-程序员宅基地

文章浏览阅读2.9k次,点赞5次,收藏12次。 在安装过Tensorflow后,后安装Keras默认将TF作为后端,Keras实现卷积网络的代码十分简洁,而且keras中的callback类提供对模型训练过程中变量的检测方法,能够根据检测变量的情况及时的调整模型的学习效率和一些参数. 下面的例子,MNIST数据作为测试import pandas as pdimport numpy as npimport matplotlib.pyp..._cnn 手写数字识别 99正确率

实现虚拟机和主机之间的文件传输_虚拟机传输文件-程序员宅基地

文章浏览阅读3.7w次,点赞35次,收藏222次。用Xftp/WinSCP/vmtools等方法实现虚拟机和主机之间的文件传输(已更新3的链接)_虚拟机传输文件

ant design pro v5 动态路由_antd5 动态路由-程序员宅基地

文章浏览阅读3.7k次,点赞5次,收藏23次。ant design pro v5 动态路由ant design pro v5 动态路由1.添加模拟数据2.添加request请求2.修改app.tsx文件4.app.tsx 完整代码ant design pro v5 动态路由1.添加模拟数据mock/menu.tsexport default { '/api/getMenuList': { routes: [ { path: '/user', layout: false, r_antd5 动态路由

推荐文章

热门文章

相关标签