一 GC的一些基本情况:

  1. GC收集情况:频繁收集年轻代,较少回收老年代,基本不动永久代(元空间),由此可以看到,在GC中,大多数是对堆空间的回收
  2. 那么在java中,是如何判断一个对象是否是个垃圾呢? 简单来说:当一个对已经不再被任何存活对象继续引用时,就可以宣布为死亡

二 判断对象是否存活的方式:

1.引用计数算法:引用计数算法(Reference Counting)比较简单,对每个对象保存一个整型的引用计数器属性,用于记录对象被引用的情况。

例如:有对象objA,与objB,如果objA指向了objB,那么objB中的引用计数器就会+1。当objA对objB的引用失效时,objB的引用计数器就-1.当objB的引用计数器的值为0时,则可以被回收。

附上代码:
package com.cdc.gc.demo;/*** @author cdc* @email c925638766@163.com* @date 2020/7/29 17:38* 测试在java中是否用了引用计数算法标记垃圾*  -XX:+PrintGCDetails***/
public class RFCount {private byte[] buff=new byte[1024*1024*5];//5MBObject reference=null;//引用public static void main(String[] args) {RFCount rfCount1=new RFCount();RFCount rfCount2=new RFCount();rfCount1.reference=rfCount2;//将对象1的属性指向对象2,构成引用rfCount2.reference=rfCount1;//将对象2的属性指向对象1,构成引用//解除引用rfCount1=null;rfCount2=null;//System.gc();}
}

在这里,首先通过rfCount1指向了堆中的RFCount(),假设该地址为0x1122,rfCount2指向的RFCount()地址假设为0x2233。这时0x1122与0x2233中的引用计数器都为1。之后在通过rfCount1中的reference指向rfCount2,即0x2233的地址再次被指向,引用计数器+1,即为2;同理0x2233的引用计数器也+1。之后再交rfCount1与rfCount2分别=null,即断开引用,引用失效,那么0x1122与0x2233的计数器分别-1,即为1。此时通过-XX:+PrintGCDetails参数,打印GC详细信息。

当System.gc()被注释起来后,即没有显式的调用gc时,控制台打印的信息:
"C:\Program Files\Java\jdk1.8.0_202\bin\java.exe" -XX:+PrintGCDetails "-javaagent:F:\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=49753:F:\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_202\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\rt.jar;F:\Java自学\jvm\JVMDemo\out\production\JVMDemo;F:\Maven_jars\junit\junit\4.11\junit-4.11.jar;F:\Maven_jars\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar" com.cdc.gc.demo.RFCount
HeapPSYoungGen      total 75776K, used 16742K [0x000000076b700000, 0x0000000770b80000, 0x00000007c0000000)eden space 65024K, 25% used [0x000000076b700000,0x000000076c759bd0,0x000000076f680000)from space 10752K, 0% used [0x0000000770100000,0x0000000770100000,0x0000000770b80000)to   space 10752K, 0% used [0x000000076f680000,0x000000076f680000,0x0000000770100000)ParOldGen       total 173568K, used 0K [0x00000006c2400000, 0x00000006ccd80000, 0x000000076b700000)object space 173568K, 0% used [0x00000006c2400000,0x00000006c2400000,0x00000006ccd80000)Metaspace       used 3196K, capacity 4496K, committed 4864K, reserved 1056768Kclass space    used 345K, capacity 388K, committed 512K, reserved 1048576KProcess finished with exit code 0

在这里可以看到,年轻代中的总内存是75776k,使用的是16742k,老年代使用为0k。

当System.gc()没有注释起来后,即显式的调用gc时,控制台打印的信息:
"C:\Program Files\Java\jdk1.8.0_202\bin\java.exe" -XX:+PrintGCDetails "-javaagent:F:\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=49963:F:\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_202\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\rt.jar;F:\Java自学\jvm\JVMDemo\out\production\JVMDemo;F:\Maven_jars\junit\junit\4.11\junit-4.11.jar;F:\Maven_jars\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar" com.cdc.gc.demo.RFCount
[GC (System.gc()) [PSYoungGen: 15442K->696K(75776K)] 15442K->704K(249344K), 0.0018542 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 696K->0K(75776K)] [ParOldGen: 8K->626K(173568K)] 704K->626K(249344K), [Metaspace: 3132K->3132K(1056768K)], 0.0075210 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
HeapPSYoungGen      total 75776K, used 1951K [0x000000076b700000, 0x0000000770b80000, 0x00000007c0000000)eden space 65024K, 3% used [0x000000076b700000,0x000000076b8e7c68,0x000000076f680000)from space 10752K, 0% used [0x000000076f680000,0x000000076f680000,0x0000000770100000)to   space 10752K, 0% used [0x0000000770100000,0x0000000770100000,0x0000000770b80000)ParOldGen       total 173568K, used 626K [0x00000006c2400000, 0x00000006ccd80000, 0x000000076b700000)object space 173568K, 0% used [0x00000006c2400000,0x00000006c249c9a0,0x00000006ccd80000)Metaspace       used 3180K, capacity 4496K, committed 4864K, reserved 1056768Kclass space    used 344K, capacity 388K, committed 512K, reserved 1048576KProcess finished with exit code 0

可以看到gc的发生,并且年轻代中的已用空间为1951k,可以判断出,堆中的0x1122与0x2233都被回收了。

结论:

1.在java中,并没有使用引用计数算法来进行垃圾回收。
2.引用计数器的优点:实现简单,垃圾对象便于辨识;判断效率高,回收没有延迟性
3.引用计数器的缺点:
①.它需要单独的字段存储计数器,这样的做法增加了存储空间的开销;
②.每次赋值都需要更新计数器,伴随着加法和减法操作,这增加了时间开销;
③.引用计数器有一个严重的问题,即无法处理循环引用的情况。这也是java没有采用引用计数算法的原因。但是在python中,使用了引用计数算法

循环引用:

2.可达性分析(根搜索算法,追踪性垃圾收集):要想了解可达性分析,就必须先知道里面的一个重要的东西:GC Roots。

(1).GC Roots:所谓 "GC Roots"根集合就是一组必须活跃的引用,附上图片一张

常见的GC Roots有哪些?
1).虚拟机栈中引用的对象比如:各个线程被调用的方法中使用到的参数,局部变量等
2).本地方法栈内JNI(通常所说的本地方法)引用的对象
3).方法区中类静态属性引用的对象比如:字符串常量池(String Table)里的引用
4).所有被同步锁synchronized持有的对象
5).java虚拟机内部的引用比如:基本数据类型对应的Class对象,一些常驻的异常对象(如:NullPointException、OutOfMemoryError),系统类加载器
6).反映java虚拟机内部情况的JMXBean,JVMTI中注册的回调、本地代码缓存等

(2).与引用计数相比,可达性分析的的一些不同:可达性分析算法不仅同样具备实现简单和执行高效等特点,更重要的是该算法可以有效地解决在引用计数器算法中循环利用的问题,防止内存泄露的发生

(3).基本思路:

1).可达性分析算法是以根对象集合(GC Roots)为起始点,按照从上至下的方式搜获被根对象集合所连接的目标对象是否可达
2).使用可达性分析后,内存中的存活对象都会被根对象集合直接或间接连接着,搜索所走过的路径称为引用链(Reference Chain)
3).如果目标对象没有与任何引用链相连,则是不可达的,就意味着该对象已经死亡,可以标记为垃圾对象
4).在可达性分析算法中,只有能够被根对象集合直接或间接连接的对象才是存活对象

(4).实现:在gc被调用之前,会调用对象中的finalize()方法,来对对象进行回收(finalization机制)。由于这是每个对象都拥有的方法,所以将它定义在了Object类中。

finalization机制:
①.基本信息:
                    1).java语言提供了对象终止(finalization)机制来允许开发人员提供对象被销毁之前的自定义处理逻辑2).当垃圾回收器发现没有引用指向一个对象,即:垃圾回收此对象之前,总会先调用这个对象的finalize()方法3).finalize()方法允许在子类中被重写,用于在对象被回收时进行资源释放。通常在这个方法中进行一些资源释放的工作,比如关闭文件,套接字和数据库链接等
②.finalize()方法的一些注意事项:永远不要主动调用某个对象的finalize()方法,应该交给垃圾回收机制调用。理由包括如下三点:

1).在finalize()时可能会导致对象复活
2).finalize()方法的执行时间是没有保障的,它完全由GC线程决定,极端情况下,若不发生GC,则finalize()方法将没有执行机会
3).一个糟糕的finalize()方法会严重影响GC的性能

③.由于finalize()方法的存在,虚拟机中的对象一般处于三种可能的状态。如果从所有的根节点都无法访问到某个对象,说明对象已经不再使用了。一般来说,此对象需要被回收。但事实上,也并非是"非死不可"的,这时候它们暂时处于”缓刑"阶段。 一个无法触及的对象有可能在某一个条件下"复活"自己,如果这样,那么对它的回收就是不合理的,为此,定义虚拟机中的对象可能的三种状态。如下:
1).可触及的:从根节点开始,可以到达这个对象
2).可复活的:对象的所有引用都被释放,但是对象有可能在finalize()方法中复活
3).不可触及的:对象的finalize()方法被调用,并且没有复活,那么就会进入不可触及状态。不可触及的对象不可能被复活,因为finalize()方法只会被调用一次

以上3种状态中,是由于finalize()方法的存在进行的区分。并且只有在对象不可触及时才可以被回收。

④.可达性分析对垃圾的标记过程:
1).如果对象obj到GC Roots没有引用链,则进行第一次标记
2).进行筛选,判断此对象是否有必要执行finalize()方法     - 如果对象obj没有重写finalize()方法,或者finalize()方法已经被虚拟机调用过,则虚拟机视为"没有必要执行",obj被判定为不可触及的- 如果对象obj重写了finalize()方法,且还未执行过,那么obj会被插入到F-Queue队列中,由一个虚拟机自动创建的、低优先级的finalizer线程触发其finalize()方法执行- finalize()方法是对象逃脱死亡的最后机会,稍后GC会对F-Queue队列中的对象进行第二次标记。- 如果这期间obj在finalize()方法中与引用链上的任何一个对象建立了联系,那么在第二次标记时,obj会被移除"即将回收"集合。- 之后,对象会再次出现没有引用存在的的情况。在这个情况下,finalize()方法不会被再次调用,对象会直接变成不可触及的状态。- 也就是说,一个对象的finalize()方法只会被调用一次
附上在finalize()方法中,对象的复活代码:
package com.cdc.gc.demo;/*** @author cdc* @email c925638766@163.com* @date 2020/8/4 23:37* 测试finalize()方法,测试对象是否可以被复活*/
public class CanReLiveDemo {private static CanReLiveDemo obj;//    @Override
//    protected void finalize() throws Throwable {//        super.finalize();
//        System.out.println("调用当前类重写的finalize()方法");
//        obj=this;//待回收的对象在finalize()方法中与引用链重新建立联系
//    }public static void main(String[] args) {try {obj=new CanReLiveDemo();//与堆区的内容建立引用obj=null;//断开引用System.out.println("第1次 gc");System.gc();//显式调用gc()Thread.sleep(2000);//由于finalizer线程的优先级低,防止finalize方法没来得及调用if (obj==null){System.out.println("obj is dead");}else {System.out.println("obj is alive");}System.out.println("第2次 gc");obj=null;//断开引用System.gc();//显式调用gc()Thread.sleep(2000);//由于finalizer线程的优先级低,防止finalize方法没来得及调用if (obj==null){System.out.println("obj is dead");}else {System.out.println("obj is alive");}} catch (Exception e) {e.printStackTrace();}}
}
当finalize()方法被注释时,即对象没有重写时,控制台打印的信息:
"C:\Program Files\Java\jdk1.8.0_202\bin\java.exe" "-javaagent:F:\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=51714:F:\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_202\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\rt.jar;F:\Java自学\jvm\JVMDemo\out\production\JVMDemo;F:\Maven_jars\junit\junit\4.11\junit-4.11.jar;F:\Maven_jars\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar" com.cdc.gc.demo.CanReLiveDemo
第1次 gc
obj is dead
第2次 gc
obj is deadProcess finished with exit code 0

在这里,由于finalize()方法被注释起来了,也就是该对象并没有重写finalize()方法,因此实际上是使用的父类也就是Object类中的的finalize()方法, protected void finalize() throws Throwable { }。在第一次gc时,此时的obj已经与堆中的对象断开了连接,也就是堆中的对象没有与GC Roots搭上线,处于可复活状态,但是在之后调用finalize()方法时发现,并没有重写,所以对象直接变为了不可触及状态,被回收掉了。所以在第一次与第二次gc时,均输出 obj is dead

当finalize()方法没有被注释,即重写了finalize()方法时,控制台打印的信息:
"C:\Program Files\Java\jdk1.8.0_202\bin\java.exe" "-javaagent:F:\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=51902:F:\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_202\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\rt.jar;F:\Java自学\jvm\JVMDemo\out\production\JVMDemo;F:\Maven_jars\junit\junit\4.11\junit-4.11.jar;F:\Maven_jars\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar" com.cdc.gc.demo.CanReLiveDemo
第1次 gc
调用当前类重写的finalize()方法
obj is alive
第2次 gc
obj is deadProcess finished with exit code 0

在这次的过程中,由于finalize()方法被重写了,在进行第1次gc时,调用finalize()方法,此时通过 obj=this 使得堆中的对象与GC Roots搭上了线,被复活了,因此第1次输出的结果是 obj is alive;但是第2次gc时,由于finalize()方法只能被调用一次,所以此时的对象无法再次复活,输出 obj is dead。

引用计数与可达性分析相关推荐

  1. 对象是否要被回收(引用计数和可达性分析算法)

    java堆和方法区主要存放各种类型的对象(方法区中也存储一些静态变量和全局常量等信息),那么我们在使用GC对其进行回收的时候首先要考虑的就是如何判断一个对象是否应该被回收.也就是要判断一个对象是否还有 ...

  2. JVM—引用计数和可达性分析算法(存活性判断)

    1 引用计数算法 1.1 算法思想   给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:   当引用失效时,计数器值就减1:   任何时候计数器为0时的对象就是不能再被使用. 1. ...

  3. 【JVM】引用计数和可达性分析算法详解

    前言 JVM堆中几乎存放了所有对象的实例,那么垃圾收集器怎么确定哪些对象还"存活"着,哪些已经"死去"呢?本文主要介绍判断对象是否存活算法引用计数算法和可达性分 ...

  4. 引用计数器法 可达性分析算法_面试官:你说你熟悉jvm?那你讲一下并发的可达性分析...

    持续输出原创文章,点击蓝字关注我吧 上面这张图是我还是北漂的时候,在鼓楼附近的胡同里面拍的. 那天刚刚下完雨,路过这个地方的时候,一瞬间就被这五颜六色的门板和自行车给吸引了,于是拍下了这张图片.看到这 ...

  5. DPDK mbuf引用计数出错的分析

    在打开这些日志时,直接在运行了一会儿后进程直接退出了,然后查看DPDK日志,看到了另一个狐疑的现象:前言:在调试多流拥塞调度下载的过程中,出现了下载一半时卡住的现象,几经查看,在看遍了不同的现象后,在 ...

  6. java gc 对象可达性_JVM垃圾回收系列---GC Roots可达性分析

    JVM的垃圾回收对于Java开发人员来说是比较透明的,本文采用问答的形式进行展开,希望能够解释下垃圾回收的一些问题.那么首先第一个问题 问:什么样的对象会被回收. 答:已经死亡的对象,不可达的对象,肯 ...

  7. JVM学习 谁是垃圾?判断对象是否能被垃圾回收 可达性分析 四大引用

    系统性学习JVM请点击JVM学习目录 为什么要垃圾回收 为什么要进行垃圾回收?做任何事之前我们都要搞清做这件事的原因.当我们在运行java项目时,如果项目比较大,它会实例化很多很多对象,多到我们的内存 ...

  8. 【Android 内存优化】Java 内存模型 ( Java 虚拟机内存模型 | 线程私有区 | 共享数据区 | 内存回收算法 | 引用计数 | 可达性分析 )

    文章目录 一. Java 虚拟机内存模型 二. 程序计数器 ( 线程私有区 ) 三. 虚拟机栈 ( 线程私有区 ) 四. 本地方法栈 ( 线程私有区 ) 五. 方法区 ( 共享数据区 ) 1. 方法区 ...

  9. 深入理解JVM03--判断对象是否存活(引用计数算法、可达性分析算法,最终判定),Eclipse设置GC日志输出,引用

    本文是基于周志明的<深入理解Java虚拟机> 堆中几乎存放着Java世界中所有的对象实例,垃圾收集器在对堆回收之前,第一件事情就是要确定这些对象哪些还"存活"着,哪些对 ...

  10. 深入理解JVM(三)——JVM之判断对象是否存活(引用计数算法、可达性分析算法,最终判定),Eclipse设置GC日志输出,引用

    本文转载自https://blog.csdn.net/ochangwen/article/details/51406779 本文是基于周志明的<深入理解Java虚拟机> 堆中几乎存放着Ja ...

最新文章

  1. 我以前一直没有真正理解支持向量机,直到我画了一张图!
  2. JS模块化工具requirejs教程02
  3. 如何制定好的方案之三:实施策略是关键
  4. TCP/IP(五):TCP 协议详解
  5. 学习韩立刚老师IT运维课程,成为韩立刚老师正式学生,在全国范围为你就近推荐工作。...
  6. 数据结构【队列专题】
  7. 关于scrollIntoView()不能使输入框显示在可视区域的问题
  8. 腾讯音乐娱乐集团Q3财报亮眼,营收与付费用户规模增速领跑全球
  9. (转)调用System.gc没有立即执行的解决方法
  10. idea生成类注释和方法注释的方法
  11. 光伏组件为何出现白色线条?
  12. myeclipse下加VSS版本控制插件
  13. LSM303D磁力计数据读取实验
  14. Redis基础--Redis 4.0 常用配置
  15. steer clear of用法
  16. 移动端背景图片自适应
  17. 重新认识 D 编程语言 —— 基础篇
  18. [Mark]The problems solutions of vmware vsphere
  19. 培养工作以外的兴趣爱好很重要
  20. [转]日语快速学习原则和方法!

热门文章

  1. 001_KNN与线性分类器
  2. 【 jvm-sandbox-repeater】环境搭建部署
  3. ABB机器人DSQC406 3HAC036301-00104伺服驱动器故障报警维修
  4. 今日头条java后端四面_今日头条笔试第二批后端开发第一题java实现
  5. 需求分析-业务需求、用户需求、功能需求
  6. cad图纸批量转换pdf
  7. 数字化成熟度评估模型一文读尽
  8. FixFox 打包xpi扩展
  9. 电机系列(1) - foc最基本原理、clark变换 、park变换、附代码
  10. 2022年自然语言处理行业研究报告