GC算法慢慢演化,进化到了现在的分代GC。其进化过程 标记-清除算法 –> 标记-复制算法 –> 标记-整理算法 –> 分代算法。
在介绍算法之前,我们知道Java是动态加载。其特点:
1.具有层级关系,由Bootstrap class loader –> Extension class loader -> System class loader (App Class Loader)-> User Defined Class Loader。
2.委派加载方式,加载一个类时,先看父类是否已经加载,只有父类无法加载,子类才会尝试加载,这确保了应用程序加载的是同一个类(同一份代码)。
3.使类具有使用限制,父类无法访问子类加载的类,而子类可以使用父类加载的类。
4.虽然加载类不能卸载其加载的类,但可以删除当前加载类。
如图:
通过Java的动态加载机制我们可以知道,java的一个live对象,可以从根(最顶端的加载类)处追查到。了解了这个我们再来具体的GC算法。
标记-清除算法:
通过将可以追溯到的对象打标记,然后将没有标记的对象删除。这种算法的缺点是会造成内存碎片。
标记-复制算法:
将内存一分为二,将未标记的对象删除,然后将标记的对象复制到另一块。这种算法虽然避免了内存碎片问题,但却带来了内存浪费的问题(有一半内存时空的)。
标记-整理算法:
这种算法将未标记的对象删除,然后将标记的对象进行内存整理。这种算法虽避免了前两种算法的缺陷,但却带来了效率低下的问题。
分代算法:
这种算法可根据应用程序的需要进行算法选择及参数调整,下节我们再具体聊下GC的参数调整。