为什么小堆上的完整gc需要5秒?

我在3年前的Solaris系统上运行J2EE应用程序,使用的堆大约为300 MB。 从gc日志我看到,每天触发几次的完整gc大约需要5秒,每次恢复大约200 MB。 一个完整的gc在如此小的堆上花了这么长时间的原因是什么?

我运行java 1.6.0_37。

缓慢的完整GC(以及次要GC)主要是硬件设置不佳,其次是软件配置(即GC人体工程学),最后是堆中的对象数量。

查看硬件,您在Solaris上使用的CPU型号和供应商是什么? 它是一个具有多个核心的SMP系统。 每个核心有多个线程吗? 您的GC是否利用系统上所有可用的虚拟处理器,即垃圾收集是否分布在多个处理器上?

使完整GC执行速度缓慢的另一种情况是,如果堆的一部分从主内存中换出。 在这种情况下,换出的内存页必须在垃圾收集期间交换,这可能是一个相当耗时的过程。 在这种情况下,您没有在计算机上安装足够的物理内存。

系统上的任何其他应用程序是否竞争相同的物理资源,即CPU和内存?

看看GC人体工程学,您使用的是哪个收集器? 我建议使用多个收集器线程的并行吞吐量收集器或G1收集器。 我还建议使用NUMA配置。

一些一般规则:

  • 更好的硬件和GC人体工程学,单个垃圾收集执行得越快。
  • 应用程序创建的对象越少越小,垃圾收集器运行的频率就越低。
  • 创建的长寿命对象越少,完整垃圾收集器运行的频率就越低。

有关GC人体工程学的更多信息, 请访问 : http : //www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html