前沿:主流的虚拟机实现都采用了分代收集的思想,把整个堆区划分为新生代和老年代;新生代又被划分成Eden空间、 From Survivor 和 To Survivor 三块区域
新生代采用复制算法收集内存,而老年代采用标记-清除算法收集内存。因为新生代比较多并且大都是朝生夕灭的,所以适合复制算法,效率高,实现简单。而老年代的不经常动,比较适合标记-清除方法。https://www.cnblogs.com/xiarongjin/p/8309839.html
新生代GC MinorGC 是指发生在新生代的GC,大多数对象都是短暂的,所以此GC也非常频繁。
老年代GC MajorGC FullGC 是老年代的GC,一般较慢。
2.垃圾回收算法
标记-清除算法 核心是标记与清除两部分,先标记出所有需要回收的对象,标记完成后统一回收。缺点是效率低,不连续空间,提前进行垃圾回收。
复制算法 不是太明白?? 核心:将空间分为两个部分,当一块用完后,将存活对象分到另外一块空间。然后将使用过的空间一次性清理。每次只对半个区域进行回收
不会产生不连续的,只需要移动顶端指针就可以了。缺点是内存空间浪费
标记-整理算法 核心是也是想标记,然后不是对可回收的空间直接清除,而是将存活的向一遍移动,然后清除边界以外的部分。
分代收集算法 核心是将Java堆分为新生代和老年代。新生代中采用复制算法。而老年代中采用标记-清理或者标记-整理进行回收。
参考为何新生代需要两个survive区域https://www.jianshu.com/p/2caad185ee1f
3.垃圾收集器
并行和并发
Java
并行 Parallel:多条垃圾收集线程并行工作,但是此时用户线程仍然在等待。
并发 Concurrent:用户线程与垃圾收集线程共同执行,用户线程也运行。
CMS收集器-并发收集,低停顿
CMS是获取最短回收停顿时间为目标的收集器。一些服务器需要最短的系统停顿时间,以给用户带来最好的体验。他是基于“标记-清除”算法为实现的。
主要经过4个步骤:初始标记;并发标记;重新标记;并发清除。
1)初始标记和并发标记都要Stop The World。初始标记是标记一下GC Root能直接关联的对象,快。
2)并发标记是进行Tracing的过程。--------------那什么是GC root Trancing呢?个人判断是从根节点向下。慢
3)重新标记:修复并发标记期间,用户程序继续运作而导致的标记变动的记录。较快
4)并发清除 与用户进程一起运行,并发运行。慢
缺点:1)对CPU资源敏感;2)由于标记-清除方法会产生内存碎片。
G1收集器
G1回收器会将整个堆划分为大小一样的独立区域(Region),新生代和老年代不再又物理隔离。
特点:
并行与并发;利用多CPU,多核环境下的硬件优势来缩短停顿时间。
分代收集,分代处理新对象和老对象,收集效果更好
空间整合 G1收集器整体上是标记-整理,局部上是复制。没有碎片。
主要经过4个步骤:初始标记;并发标记;最终标记;筛选回收。
1)初始标记:标记和root关联的对象。并发标记一样的
2)最终标记:和上面的重新标记一样:还是修正那个用户程序影响的标记。虚拟机将对象变化记录在线程Remembered Set Log中去,然后最终标记阶段将这些数据合并到Remembered Se中去。
3)筛选回收:将各个Region回收价值排序,然后指定计划回收。
Serial收集器
单线程,要停止其他工作线程
PerNew收集器
4.内存分配策略
对象优先在Eden分配 如果空间不足,会进行一次Minor GC(新生代垃圾回收)。
大对象直接进入老年代。 大对象指的是大量连续内存空间的Java对象。
长期存活的对象将进入老年代。老年代就是年龄阈值达到了,改阈值是经过一次Minor GC并且在Survivor空间中计算出来的