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

Java 为什么小堆上的完整gc需要5秒?,java,jakarta-ee,garbage-collection,Java,Jakarta Ee,Garbage Collection,我正在3年历史的Solaris系统上运行一个J2EE应用程序,使用的堆大约为300MB。从gc日志中我看到,每天触发几次的完整gc大约需要5秒,每次恢复大约200 MB。完整gc在这么小的堆上花费这么长时间的原因是什么 我运行java 1.6.0_37。缓慢的完全GC(以及较小的GC)主要是由于硬件设置不佳,其次是软件配置(即GC工效学),最后是堆中驻留的对象数量 看看硬件,您在Solaris上使用的CPU型号和供应商是什么?它是一个具有多个核心的SMP系统。每个核心是否有多个线程?您的GC是否

我正在3年历史的Solaris系统上运行一个J2EE应用程序,使用的堆大约为300MB。从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工效学的更多信息:

缓慢的完全GC(以及较小的GC)主要是由于硬件设置不佳,其次是软件配置(即GC工效学),最后是堆中驻留的对象数量

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

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

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

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

一些一般规则:

  • 硬件和GC工效学越好,单个垃圾收集的执行速度就越快
  • 应用程序创建的对象越少、越小,垃圾收集器运行的频率就越低
  • 创建的长寿命对象越少,完整垃圾回收器运行的频率就越低
有关GC工效学的更多信息:

这实际上取决于堆中存储的对象数量。代码是否创建和删除了许多对象?很多/所有节目都会这样吗?>很有趣。所以物体的数量是这里的重要因素,而不是大小?如果是,如何查看我创建了多少对象?您可以停止压缩,因为默认情况下,gc执行部分堆内存压缩。压缩可能会增加gc时间。这实际上取决于堆中存储的对象数量。代码是否创建和删除了许多对象?很多/所有节目都会这样吗?>很有趣。所以物体的数量是这里的重要因素,而不是大小?如果是,如何查看我创建了多少对象?您可以停止压缩,因为默认情况下,gc执行部分堆内存压缩。压缩可能会增加gc时间。感谢您的回复。我想我不能责怪服务器。除了我的应用程序之外,它没有使用过,我有几个内核,每个内核有两个线程,还有大量可用的可用内存。查看vmstat,系统的负载非常低。如何查看创建的对象数?我可以看到我在gc日志中使用了多少堆,但我不知道我创建了多少对象。(我会尽快回复您有关收集器的信息)我有Solaris和多核Sparc处理器在垃圾收集方面表现不佳的经验。虽然您有一个SMP系统,没有负载,并且利用了所有可用的内核/线程,但CPU的性能可能很差。我确信这是真的,但是您和上面的评论都说,创建大量对象会使gc变慢,这两个问题都没有回答我如何衡量这一点。你有什么好的建议吗?再次感谢您的回复。我认为只有通过垃圾收集器本身的检测才能实现。但是您可以做的是一个测试,在该测试中,您创建的垃圾收集对象越来越少,越来越大,并将其与当前情况进行比较,看看释放的对象数量如何影响GC延迟。这意味着年轻一代和老一代都将被并行线程收集-XX:+UseParallelGC-XX:+UseParallelOldGC-XX:+UseNUMA-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-XX:+PrintHeapAtGC-Xloggc:gc.log您可以使用XX:ParallelGCThreads=X来控制并行gc线程的数量,i