在java虚拟机中需要对两部分的内容进行回收,一部分是java堆中的对象,一部分是无用的类,
判断是否为无用的类的三个条件:
1.该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例;
2.加载改类的ClassLoader已经被回收
3.该类对应的java.lang.Class对象没有在任何地方引用,无法在任何地方通过有反射访问改类的方法。
在对垃圾进行回收的实现上通常有三种方法:
1.标记-清除算法
思想:标记处所有需要回收的对象,在标记完成后统一回收被标记的对象。
缺点:
1.效率不高
2.标记清除之后会产生大量不连续的内存碎片,空间碎片过多可能会导致以后再程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前出发另一次垃圾收集动作。
改进1:复制算法,复制算法基于标记清除算法的思想,做了改进:它将可用内存按照容量大小划分为大小相等的两块,每次只使用其中一块,当这一块内存用完了,就将还存活着的对象复制到另一块上面,然后再把使用过的内存一次清理.
缺点:将内存缩小为原来的一半.
改进2:将内存分为一块较大的Eden空间和两块较小的Survior空间,每次使用Eden和其中Survior,当回收时候,将Eden和Survior中还存活的对象复制到另一个Survior上,最后清理到Eden和使用过的Survior空间,当另一个Survior内存不够用的的时候,需要依赖老年代内存进行担保。
2.标记-整理算法
思想 : 让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
3.分代收集算法
思想:分代收集算法没有新的思想,而是根据对象存货周期的不同将内存划分成几块,一般分为新生代和老年代,在新生代中,每次垃圾收集时都发现有大量对象死去,只有少量对象存活,则选用复制算法,而老年代中因为存活效率高,没有额外空间对其进行分配担保,就必须使用 标记-清除 法进行回收。