文章目录
前言
随着程序的运行,内存中存在的实例对象和变量不断增加,占用的资源也越来越多,若不对其进行吃力,程序的性能会大受影响,甚至可能会让系统出现异常。为此,人们研究出了垃圾回收机制来处理该问题。
一、jvm的垃圾回收机制
什么是垃圾回收
垃圾回收(Garbage Collection,GC),顾名思义就是释放垃圾占用的空间,防止内存泄露。有效的使用可以使用的内存,对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。
什么样的垃圾需要回收
没有任何应用的对象就可以被回收。
确认是否回收的算法
- 引用计数算法:对象被引用,计数+1,删除引用,计数-1,到达0时回收。缺点:若两对象互相引用,无法回收。
- 可达性分析算法:确定“根对象”,以根对象为起点,根据对象之间的关系搜索出一条“引用链”,在引用链的对象就存回,不在的就回收。
可作为根对象的对象:
- 虚拟机栈中的引用对象(正在运行的方法引用的变量参数)
- 方法区中类静态属性引用的对象(static关键字声明的字段)
- 方法区中常量引用的字段(final关键字声明的字段)
- 本地方法栈中引用的对象(native对象)
- java虚拟机内部的引用(系统内部的对象)
回收垃圾的算法
标记-清除: 将可回收的对象之间清除。优点:块,标记了就直接删除。 缺点:执行效率不稳定,内存碎片化。
标记-整理: 将有用对象移到一端,清除剩下的。优点:解决了内存碎片化问题。缺点:慢,由于移动了可用的对象,所以需要更新对象的引用。
标记-复制: 将内存空间分为两块,回收时将存回对象复制到未使用空间,然后清除之前空间的所有对象,然后交换二者角色。 优点:解决上述所有问题。 缺点:占空间。
二、jvm垃圾回收具体流程
jvm不会单独采用某种算法,而是会将三种算法协同合作。
众所周知,内存主要被分为年轻代和老年代还有持久代,年轻代又分为伊甸园和from幸存者还有to幸存者,持久代在Sun HotSpot中就是指方法区,而且有些JVM中根本就没有持久代这中说法。
新生代的垃圾回收比较频繁,而老年代的垃圾回收就很久一次。(例:处理日用垃圾和过年大扫除的区别)
伊甸园装满对象就进行MinorGC,此时进行可达性分析。MinorGC使用标记复制算法,将伊甸园对象放入to幸存者,然后清理伊甸园,然后to和from交换定义。里面的对象“幸存值+1”,幸存值代表经历多少次MinorGC,达到15时就会将对象放入老年代。
老年代满时,开始进行FullGC,此时老年代和年轻代都会清理一次,老年代使用的是标记-整理算法或标记-清除算法。
总结
这是本人对垃圾回收算法最简单的解释,日后有时间写篇长的。