存放已经被加载的类信息、常量、静态变量和即时编译器编译后的代码数据,即永久代。
在jdk1.8之后,被元数据区取代。原方法区分成两部分:
加载的类信息:保存在元数据区运行时常量池:保存在堆中串行垃圾回收器只会使用一个CPU或一个收集线程完成垃圾收集工作。并且在垃圾回收的时候,必须暂停其他所有的工作线程(Stop the World),直到收集完成。
串行垃圾回收器有两种:Serial、Serial Old,一般搭配使用。通过**-XX:+UseSerialGC开启**
Serial:新生代、复制算法
Serial Old:老年代、标记整理算法
并行垃圾回收器通过多线程运行垃圾收集,也会Stop the World。适合Server模式以及多CPU环境,一般会和CMS搭配使用。
ParNew:新生代、复制算法。Serial的多线程版本,默认开启的收集线程数和CPU数量一样。通过-XX:+UseParNewGC开启和Serial Old收集器组合进行内存回收
Parallel Scavenge:**新生代、复制算法。**关注吞吐量(吞吐量=代码运行时间 / (代码运行时间+垃圾手机时间))。高效率利用CPU时间。
Parallel Old:老年代、标记整理法。Parallel Scavenge的老年代版本。一般使用Parallel Scavenge+Parallel Old组合使用
由于垃圾回收线程可以和用户线程同时运行,也就是说它是并发的,那么它会对CPU的资源非常敏感,CMS默认启动的回收线程数是(CPU数量+3)/ 4,当CPU<4个时,并发回收是垃圾收集线程就不会少于25%,而且随着CPU减少而增加,这样会影响用户线程的执行。而且由于它是基于标记-清除算法的,那么就无法避免空间碎片的产生。CMS收集器无法处理浮动垃圾(Floating Garbage),可能出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。
所谓浮动垃圾,在CMS并发清理阶段用户线程还在运行着,伴随程序运行自然还会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在当次收集中处理掉它们,只能留待下一次GC时再清理掉。
G1从整体上来看是基于标记-清除算法的,但是局部上基于复制算法。这样的好处是空间整合做的比较好,不会产生空间碎片。
G1也是并发与并行的,充分利用多CPU、多核的硬件环境来缩短Stop the World的时间
G1还是分代收集的,但是是需要分代配合不同的垃圾收集器。因为G1中的垃圾收集器区域是分区的。
运作流程:初始标记、并发标记、最终标记、筛选回收,不会产生空间碎片,可以精确控制停顿。
G1将整个堆分为大小相等的多个Rigion区域,G1跟踪每个区域的垃圾大小,在后台维护一个优先级列表。每次根据允许的收集时间,优先回收价值最大的区域,以达到在有限时间内获取尽可能高的回收效率。
