JVM会根据generation(代)来进行垃圾回收(Garbage Collection,GC),根据下图4-9所示,一共被分为young generation(年轻代)、tenured generation(老年代)、permanent generation(永久代,perm gen),perm gen(或称Non-Heap非堆)是个异类。注意,heap空间不包括perm gen。
图4-9 JVM根据generation(代)来进行GC
绝大多数的对象都在young generation中被分配,也在young generation中被收回。当young generation的空间被填满时,GC会进行minor collection(次回收),次回收不涉及到heap中的其他generation。minor collection会根据weak generational hypothesis(弱年代假设)来假设young generation中的大量的对象都是垃圾需要回收,minor collection的过程会非常快。在young generation中,没有被回收的对象被转移到tenured generation,然而tenured generation也会被填满,最终触发major collection(主回收),这次回收针对整个heap,由于涉及到大量对象,所以比minor collection慢得多。
什么样的对象GC才会回收呢?当然是GC发现通过任何reference chain(引用链)都无法访问某个对象的时候,该对象即被回收。名词GC Roots正是分析这一过程的起点,例如JVM自己确保了对象的可到达性(那么JVM就是GC Roots),所以GC Roots就是这样在内存中保持对象可到达性的,一旦不可到达,即被回收。通常GC Roots是一个在current thread(当前线程)的call stack(调用栈)上的对象(例如方法参数和局部变量),或者是线程自身或者是system class loader(系统类加载器)加载的类以及native code(本地代码)保留的活动对象。所以GC Roots是分析对象为何还存活于内存中的利器。
从最强到最弱,不同的引用(可到达性)级别反映了对象的生命周期。(https://www.daowen.com)
Strong Ref(强引用):通常编写的代码都是Strong Ref,对应的是强可达性,只有去掉强可达,对象才被回收。
Soft Ref(软引用):对应软可达性,只要有足够的内存,就一直保持对象,直到发现内存吃紧且没有Strong Ref时才回收对象。一般可用来实现缓存,通过java.lang.ref.SoftReference类实现。
Weak Ref(弱引用):比Soft Ref更弱,当发现不存在Strong Ref时,立刻回收对象而不必等到内存吃紧的时候。通过java.lang.ref.WeakReference和java.util.WeakHashMap类实现。
Phantom Ref(虚引用):根本不会在内存中保持任何对象,只能使用Phantom Ref本身。一般用于在进入finalize()方法后进行特殊的清理过程,通过java.lang.ref.PhantomReference实现。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。