0

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

我运行 java 1.6.0_37。

4

1 回答 1

3

缓慢的完整 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

于 2013-08-23T10:40:07.590 回答