JVM的垃圾回收分析,主要从以下几方面进行:
1.如何判断对象是否可回收
2.标记对象可回收的流程
3.垃圾收集算法有哪些
4.基于不同的垃圾收集算法,有哪些垃圾收集器
判断对象是否可回收:
判断对象是否可回收的两种算法:
引用计数算法:
给对象添加一个引用计数器,有对象引用它计数器加1.引用失效就减1,计数器值为0表示改对象可回收。
优点:简单高效。
缺点:无法解决对象间相互循环引用的问题。
可达性分析算法:
通过一系列的称为“GC root”的对象作为起点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC root没有任何引用链相连,证明该对象是可回收对象。如下图:
JVM使用的是可达性分析算法,分析对象是否可回收。
但是JVM描述一个对象是否可回收,并不是仅仅通过可达性分析算法判断对象,是否被引用或没被引用这两种情况,只根据被引用或没被引用定义对象是否可回收是不全面的,比如,当内存空间足够时,则保留对象在内存。当GC后内存空间还是不足,则抛弃这些对象,
因此JVM将对象的引用分为四种,强引用,软引用,弱引用,虚引用。
强引用:类似Object obj=new Object;这类引用就是强引用,只要强引用一直存在,GC永远不会回收。
软引用:用来描述一些还有用但非必要的对象。软引用关联着的对象,在系统将要发生内存溢出之前,将会把这些对象列进回收范围之进行第二次回收,如果这次回收还没足够的内存,才会抛出溢出异常。java使用SoftReference实现。
弱引用:弱引用关联的对象,只能生存到下一次垃圾回收之前,当执行垃圾回收时,无论内存空间是否足够,都会回收掉弱引用关联的对象。java使用WeakReference实现。
虚引用:虚引用关联的对象,无法获取关联对象的实例,也不影响其生存时间,但是关联对象在被GC回收时,会收到一个系统通知。java使用PhantomReference实现。
JVM使用可达性分析算法进行对象是否可用标记流程:
进行两次标记,第一次标记并筛选,然后执行finalize方法,第二次再次标记,最终被标记的对象将被回收。
垃圾收集算法介绍:
标记-清除算法:先标记所有需要回收的对象,然后一次性清除要回收对象
优点:简单
缺点:标记过程和清除过程效率均不高;会产生大量空间碎片
复制算法:将内存分为大小相等的两块,每次只使用其中的一块,当这一块内存使用完了,将还存活的对象复制到另一块内存上,把已使用的那块内存全部清除。
优点:效率高,不会产生内存碎片,实现简单
缺点:有一半的内存不可用
标记-整理算法:复制算法在对象存活率较高时,会进行多次操作,效率变低,还有就是50%空间的浪费。标记-整理算法的提出,是根据老年代的特点设计的
主要分为两个阶段,标记阶段,将存活对象进行标记,并向一端移动,然后清除边界以外的内存。
分代收集算法:将内存划分为新生代和老年代,然后根据不同代的特点采用最合适的收集算法,一般新生代采用复制算法,老年代采用标记-整理算法和标记-清除。
HotSpot中将对内存划分为新生代和老年代,新生代又划分为伊甸园(Eden)和2个小的幸存区(Survivor),默认Eden:Survivor=8:1
每次使用内存时,只使用Eden和其中一个Survivor,回收时,将Eden和使用中的Survivor中的存活对象复制到另一个未使用的Survivor,
对象每进行一次移动,年龄+1,到达一定年龄将移到老年代。
垃圾收集器:
原文:https://www.cnblogs.com/eason-ou/p/12166715.html