1.1 理解

  • 在默认情况下,通过 System.gc()或者 Runtime. getruntime().gc()的调用,会显式触发Full GC,同时对老年代和新生代进行回收,甚至会包含方法区的回收,尝试释放被丢弃对象占用的内存 。
  • 然而 System.gc()调用附带一个免责声明,无法保证对垃圾收集器的调用
  • JVM实现者可以通过 System.gc()调用来决定JVM的GC行为。而一般情况下,垃圾回收应该是自动进行的,无须手动触发,否则就太过于麻烦了。在一些特殊情况下,如我们正在编写一个性能基准,我们可以在运行之间调用System.gc()

    1.2 代码例子

    localvarGC1方法在进行Young GC的时候没有被回收掉,在进行Full GC的时候就直接将buffer对象放入了老年代。
    image.png
    localvarGC2方法里的对象在经过young GC和Full GC后,整个对象已经被回收掉了。
    image.png
    localvarGC2方法中在进行Young GC的时候没有被回收掉,在进行Full GC的时候就直接将buffer对象放入了老年代。
    image.png
    之所以没有被回收掉是因为在自己码中最大的索引位置为2,虽然在局部变量表中只有一个位置,但buffer是占用了一个索引位置,buffer还是指引着堆中的对象,所以没有被回收掉。
    image.png
    localvarGC4方法里的对象在经过young GC和Full GC后,整个对象已经被回收掉了。
    image.png
    之所以能被回收掉是因为本来buffer在局部变量表中占据一个槽位,但它的作用域只是在静态代码块中,在静待代码块后有定义了一个value的变量,此变量就会覆盖buffer所占据的槽位,没有引用在指向堆中的byte对象,所以就可以被回收掉了。
    image.png
    localvarGC1经历4次GC后最终被回收掉了。
    image.png