Java-面试--Java8-JVM垃圾回收机制

前奏

  • 提到Java的垃圾回收机制,必须要提到Java的内存管理模型,详见 Java-面试--Java8-JVM内存模型

Java垃圾回收

Garbage Collection,GC

为什么要进行垃圾回收

  • 随着程序的运行,内存中存在的实例对象、变量等信息占据的内存越来越多,如果不及时进行垃圾回收,必然会带来程序性能的下降,甚至会因为可用内存不足造成一些不必要的系统异常。

哪些垃圾需要回收

  • 有三个区是不需要进行垃圾回收的,分别是:程序计数器、JVM栈、本地方法栈。
  • 需要进行回收垃圾的区:堆和方法区

什么时候进行垃圾回收

  • 什么样的类需要回收呢?无用的类,何为无用的类?需满足如下要求:
    1> 该类的所有实例对象都已经被回收。
    2> 加载该类的ClassLoader已经被回收。
    3> 该类对应的反射类java.lang.Class对象没有被任何地方引用。

常见的GC算法

  • 标记-清除算法(Mark-Sweep)
    • 最基础的GC算法,将需要进行回收的对象做标记,之后扫描,有标记的进行回收,这样就产生两个步骤:标记和清除。这个算法效率不高,而且在清理完成后会产生内存碎片,这样,如果有大对象需要连续的内存空间时,还需要进行碎片整理,所以,此算法需要改进。
  • 复制算法(Copying)
    • 前面我们谈过,新生代内存分为了三份,Eden区和2块Survivor区,一般Sun的JVM会将Eden区和Survivor区的比例调为8:1,保证有一块Survivor区是空闲的,这样,在垃圾回收的时候,将不需要进行回收的对象放在空闲的Survivor区,然后将Eden区和第一块Survivor区进行完全清理,这样有一个问题,就是如果第二块Survivor区的空间不够大怎么办?这个时候,就需要当Survivor区不够用的时候,暂时借持久代的内存用一下。此算法适用于新生代。
  • 标记-整理(或叫压缩)算法(Mark-Compact)
    • 和标记-清楚算法前半段一样,只是在标记了不需要进行回收的对象后,将标记过的对象移动到一起,使得内存连续,这样,只要将标记边界以外的内存清理就行了。此算法适用于持久代。

常见的GC回收器

垃圾回收算法.jpg
  • GC主要分二类,新生代GC,老年代GC;
  • 新生代GC包括:串行GC、并行GC、并行回收GC;
  • 老年代GC包括:串行GC、并行GC、CMS;
  • G1比较特殊,同时支持新生代和老年代。

GC和OOM的区别

Java Minor GC、Major GC和Full GC之间的区别?

  • Minor GC
    • Minor GC指新生代GC,即发生在新生代(包括Eden区和Survivor区)的垃圾回收操作,当新生代无法为新生对象分配内存空间的时候,会触发Minor GC。因为新生代中大多数对象的生命周期都很短,所以发生Minor GC的频率很高,虽然它会触发stop-the-world,但是它的回收速度很快。
  • Major GC
    • Major GC清理Tenured区,用于回收老年代,出现Major GC通常会出现至少一次Minor GC。
  • Full GC
    • Full GC是针对整个新生代、老生代、元空间(metaspace,java8以上版本取代perm gen)的全局范围的GC。Full GC不等于Major GC,也不等于Minor GC+Major GC,发生Full GC需要看使用了什么垃圾收集器组合,才能解释是什么样的垃圾回收。

你可能感兴趣的:(Java-面试--Java8-JVM垃圾回收机制)