一、描述一下GC以及GC回收的算法

1、Java GC采用了分代的思想,将java的堆内存分成新生代、年老代以及永久代。

2、GC的主要算法:标记-清除、标记-压缩、复制算法

3、什么是新生代:

      新生代主要存储创建时间比较新的对象。新生代会被分为三个部分eden区、from区、to区。当我们创建对象时,jvm分配内存时,会在新生代的eden区寻找合适的内存区域。当eden内存不够时,会触发minor GC操作,它会把eden中存活的对象和from区的存活对象复制到to区。当to区的年龄超过了晋升的年龄设置,对象会被提升到年老代。新生代的GC用的是复制算法。

4、什么是年老代:

      年老代主要存放的都是存活时间比较久的以及大小比较大的对象,因此老年代使用的是标记整理算法,当老年代容量满的时候,会触发Major GC,回收年老代和年轻代不再使用的对象资源。

5、什么是永久代:

      永久代是内存中的永久保存区域,主要存放class和meta(元数据)的信息。Class在被加载的时候被放入永久区域。它和它存放实例的区域不同,GC不会在主程序运行期间对永久区域进行清理。这也导致了随着被加载的class增多,永久代的区域也会越来越胀满,最终抛出OOM异常。

6、什么是标记-清除,标记-压缩算法:

      首先是标记:标记是GC通过遍历内存中哪些内存在使用,哪些没有,并做好标记。

      清除:清除掉垃圾内存,并用链表记录维护一个空闲的区域。

      压缩:为了提升性能,在删除完垃圾之后,GC会把存活的对象移动至内存头部,这样方便之后分配内存。

7、复制算法:

      复制算法将内存分为两个区间,使用次算法时,所有动态分配的对象都只分配在其中一个区间中。复制算法采用从根集合进行扫描,将存活的对象复制到空闲区,然后扫描完毕之后,将活动区的剩余一次性回收。然后活动区跟空闲区进行调换。

 

二、JVM GC怎么判断对象可以被回收

1、该对象没有被引用

2、作用域发生未捕获异常

3、程序在作用域正常执行完毕

4、 程序执行了System.exit()

5、程序发生意外终止(被杀线程等)

6、将对象设置为null(可能会逃逸)

 

三、GC的主要任务

1、分配内存

2、确保被引用的对象不会被错误回收

3、回收不再被引用的对象的内存