文章目录
GC触发条件
Minor GC触发条件
- 当Eden区满时,触发Minor GC。
Full GC触发条件
- 调用System.gc时,系统建议执行Full GC,但是不是必然执行
- 通过Minor GC后进入老年代的平均大小大于老年代的可用内存
当要触发一次Minor GC时,如果发现统计数据中Minor GC的平均晋升大小比目前old gen剩余的空间大,则不会触发Minor GC,而是直接转为Full GC。 - 方法区空间不足
运行时数据区域中的方法区,在HotSpot虚拟机中又被习惯称为永生代或者永生区,Permanet Generation中存放的为一些class的信息、常量、静态变量等数据,当系统中要加载的类、反射的类和调用的方法较多时,Permanet Generation可能会被占满,在未配置为采用CMS GC的情况下也会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出如下错误信息:
java.lang.OutOfMemoryError: PermGen space
为避免Perm Gen占满造成Full GC现象,可采用的方法为增大Perm Gen空间或转为使用CMS GC。 - 老年代空间不足,和第二点类似
旧生代空间只有在新生代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行Full GC后空间仍然不足,则抛出如下错误: java.lang.OutOfMemoryError: Java heap space 为避免以上两种状况引起的FullGC,调优时应尽量做到让对象在Minor GC阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。
OopMap
OopMap 用于枚举GCRoots
当垃圾回收时,收集线程会对栈上的内存进行扫描,看看那些位置上存储了Reference类型。如果发现了某个位置上存储的是Reference类型,就意味着这个引用所指向的对象在这一次垃圾回收过程中不能够回收。
栈上的本地变量表里面只有一部分数据是Reference类型的,为了避免每次都扫描整个栈,所以采用空间换时间的策略。在某个时候(安全点)把栈上代表引用的位置记录下来,GC时直接读取,避免了全部扫描。 HotSpot虚拟机采用了一种叫做OopMap的数据结构来记录这些引用(OopMap也帮助HotSpot实现了准确式GC),OopMap记录了栈上本地变量到堆上对象的引用关系,这些引用指向的对象不能够回收,并且可以作为根节点来进行可达性分析,查找出不能够回收的对象。
安全点
safepoint 安全点是指一些特定的位置,当线程运行到这些位置时,线程的一些状态可以被确定,比如记录OopMap的状态,从而确定GC Root的信息,使JVM可以安全的进行一些操作,比如开始GC。
上面讲到了为了快点进行可达性的分析