看了大师的讲解记录下心得:这三种算法都是基于GCroot搜索出存活的对象
1,标记-清除算法(stop-the-world );
运用GCroot根搜索出引用链条上的所有可达对象标记为存活对象;将所有未标记的对象清除,释放出内存;
特点:正向思维好理解,空间和时间都不高。内存碎片(因为无用的对象内存不是连续的因此清理后的内存也不是连续的,JVM还要维持一个空闲列表,增加一笔开销,同时在以后内存使用时候,去查找可用的内存这个效率也是很低的)。效率较低两次运算标记存活对象,查找已死对象删除已死对象。
2,标记-复制算法(适合在新生代GC);
将原有的内存分为两块,每次只用其中的一块,在垃圾回收的时候,将一块正在使用的内存中存活(GCroots根搜索的算法)的对象复制到另一块没有使用的内存中,原来的那一块全部清除
特点:内存连续,新对象分配内存不需要考虑内存碎片;but始终有一块内存空着
模型:Eden,Survivor(From,To) = 8:1:1 (公开课上NB的老师手画内存模型)第一次20%之后10%的年轻的内存处于闲置。
3,标记-整理算法;
运用GCroot根搜索出引用链条上的所有可达对象标记为存活对象,将存活的对象压缩至内存一端,按照内存地址的次序依次排列,末端内存地址之前的内存区域全部释放。
特点:该算法可以解决内存碎片问题同时还可以解决复制算法部分内存不能利用的问题
三种算法比较:
**效率:**复制算法>标记-整理算法>标记-清除算法;
**内存整齐度:**复制算法=标记-整理算法>标记-清除算法
**内存利用率:**标记-整理算法=标记-清除算法>复制算法
当下的JVM采用分代回收机制:
**新生代:**由于存活的对象相对比较少,因此可以采用复制算法该算法效率比较快。
**老年代:**由于存活的对象比较多,可以采用标记-清除算法或是标记-整理算法
思考?
复制对象到新的内存这种算法缺陷:是否会造成引用该对象的变量存放的内存地址失效,后续必然会对引用地址从新赋值给引用方?
复制算法为什么不会造成 stop-the-world ?