我在3年前的Solaris系统上运行J2EE应用程序,使用的堆大约为300 MB。从gc日志中我看到,每天触发几次的完整gc大约需要5秒钟,每次恢复大约200 MB。完全gc在如此小的堆上花了这么长时间的原因是什么?
我运行java 1.6.0_37。
答案 0 :(得分:3)
缓慢的完整GC(以及次要GC)主要是硬件设置不佳,其次是软件配置(即GC人体工程学),最后是堆中的对象数量。
查看硬件,您在Solaris上使用的CPU型号和供应商是什么?它是一个具有多个核心的SMP系统。每个核心有多个线程吗?您的GC是否利用系统上所有可用的虚拟处理器,即分布在多个处理器上的垃圾收集?
使完整GC执行速度缓慢的另一种情况是,如果堆的一部分从主内存换出。在这种情况下,换出的内存页必须在垃圾收集期间交换,这可能是一个相当耗时的过程。在这种情况下,您没有在计算机上安装足够的物理内存。
系统上的任何其他应用程序是否竞争相同的物理资源,即CPU和内存?
查看GC人体工程学,您使用的是哪个收集器?我建议使用多个收集器线程的并行吞吐量收集器或G1收集器。我还建议使用NUMA配置。
一些一般规则:
有关GC人体工程学的更多信息: http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html