当前位置: 代码迷 >> 综合 >> [翻译]Java Garbage Collection Basics Java 垃圾回收基础 之6 Java垃圾回收器
  详细解决方案

[翻译]Java Garbage Collection Basics Java 垃圾回收基础 之6 Java垃圾回收器

热度:16   发布时间:2024-01-11 07:38:07.0

Java垃圾回收器

现在你知道垃圾回收的基础知识,也了解了如何在一个示例项目上观察gc过程。本节会介绍java可用的垃圾收集器和如何在命令行启用他们。

通用堆相关参数

JAVA中有很多命令行开关。这节展示了在本文中常用的开关。

开关 描述
-Xms 设置初始堆大小
-Xmx 设置最大堆大小
-Xmn 设置年轻代大小
-XX:PermSize 设置持久代初始大小
-XX:MaxPermSize 设置持久代最大大小

Serial GC

该GC在JAVA SE 5,6 的客户端风格机器中是默认的GC。采用该GC后,minor / major gc 都是顺序收集的(使用单个虚拟CPU)。除此之外,它还使用一个标记-压缩收集方式(这种方式将老点的内存移动到堆的开始,以便新的内存分配可以在堆的末尾连续分配。)针对内存的压缩使得在堆中分配一段内存更快。

使用场景

该GC适用于那些没有低停顿时间要求的客户端风格应用。它只利用一个虚拟处理器来进行垃圾回收(正如名称所说)。在今天的硬件下,Serial GC能够高效管理一个拥有几百M的堆,(带有一个相对短的最坏停顿时间,full gc大概在几s)。
另外一个常见的场景就是用于有很多JVM实例运行在同一个机器上(某些情况下JVM实例数比可用的CPU核数还多)。在这种场景下,一个JVM只使用一个处理器来进行垃圾回收可以更好的降低对其他JVM的干扰,尽管gc时间会变得更长。这是一个折中的方案。
最后,随着只有很小内存和很少CPU的嵌入式设备的增长,Serial GC 会东山再起。

命令行开关

-XX:+UseSerialGC

Parallel GC

该GC采用多个线程来完成年轻代GC。默认的,主机有n个CPU,会使用n个垃圾回收线程。该线程数可以通过如下参数设置:

-XX:ParallelGCThreads= 线程数

在一个只有单核CPU的机器上会采用默认的垃圾回收器,即使手动指定了Parallel GC,在一个有2个CPU的机器上,该GC通常作为默认的GC,并且当有更多的CPU时,可预期的,会减少年轻代的GC 停顿时间。

使用场景

该GC通常也叫吞吐量优先GC,因为它是用多个CPU来加快应用的吞吐量。该CPU可以用于当有很多工作要做,而且长的停顿是可以接受的场景。比如:打印报告或者账单等批处理操作,或者大量查询数据库的场景。

命令行开关

-XX:+UseParallelGC

打开这个开关,你会得到一个多线程的年轻代垃圾回收器和一个单线程的年老代GC收集器。这个也会堆年老代做单线程的压缩。

-XX:+UseParallelOldGC

打开这个开关后,你会得到一个年轻代 年老代都是多线程回收的垃圾回收器,包括年老代的压缩也是多线程。HotSpot只在年老代做压缩。年轻代被认为是一个copy 收集器,所以不需要压缩。

压缩被描述为移除对象之间的空洞的一系列操作。在一次垃圾回收清扫后,在存活对象间可能会有一些空洞。压缩并移动对象来清除空洞。有的GC可能不是一个压缩型的GC。因此Parallel gc 和 parallel 压缩 gc的区别就是后者在垃圾回收清扫会压缩空间,而前者不会。

CMS gc

Concurrent Mark Sweep (CMS) 也被称为年老代的低停顿时间收集器。它尝试最小化停顿时间,因为大多数GC工作都与应用程序线程并行执行。一般来说,低停顿时间的垃圾回收器不会拷贝或者压缩存活的对象。垃圾回收时并没有移动存活的对象,如果碎片化称为一个问题,那么需要一个更大的堆。
NOTE:CMS 在年轻代的算法与parallel gc 相同。

使用场景

CMS GC 应该被用于那些要求低停顿时间,并且与垃圾收集器共享资源(译注:CPU资源吗?)的应用。比如:桌面UI应用(响应用户操作事件), Web服务器(响应请求)或者数据库(响应查询)。

命令行开关

采用CMS gc:

-XX:+UseConcMarkSweepGC

设置线程数:

-XX:ParallelCMSThreads=n

G1 GC

G1 = Garbage first
在jdk7 开始可用,并作为在长时间内CMS的替代者,G1是一个并行的,并发的,增量压缩的低停顿时间GC,并且内存布局也与前面描述的GC大不相同。这里不会讨论详细的信息。

命令行开关

-XX:+UseG1GC

  相关解决方案