当有足够的可用内存时,为什么Java垃圾收集器会启动?

时间:2011-10-18 18:14:32

标签: java garbage-collection jvm windows-server-2008-r2 jdk1.6

C#dev在这里,被迫处理Java ...我正在连接Java Web服务,这是一个相当大的内存和CPU。它。

事实:

  • 在Tomcat下运行,它是Java 1.6.x
  • 全部在Windows Server 2008 R2上,x64具有32 GB的RAM。
  • Tomcat设置为16GB RAM
  • Web Service通常消耗大约6.5 GB。

Web服务偶尔遭遇垃圾收集风暴,并且会降低处理速度(由Java Web Service供应商决定)。

我的问题,对Java GC不太了解,这就是为什么如果有足够的RAM可用,GC就会启动。是否有一些设置告诉它在没有内存的情况下踢它?

我的参考框架是.NET GC,只有在有内存压力时才会启动。

5 个答案:

答案 0 :(得分:7)

Java中有几种垃圾收集模型。您可以尝试查看哪一个对您的特定用例影响最小。参见:

通过选择合适的集合模型,我可以在Web服务中获得更顺畅/可预测的性能。

答案 1 :(得分:4)

你需要的是一个分析器。两个不错的选择是JProfiler和YourKit。要么你会告诉你到底发生了什么,所以你和这里的人都不必尝试猜测。

鉴于你写的内容,没有办法知道应用程序是否只是分配GC最终必须赶上的风暴,或者是更具异国情调的风暴。

答案 2 :(得分:3)

坦率地说,这种行为可能有很多原因。在上述情况下,您可能需要根据结果调整垃圾收集器。 Oracle在http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html

上有一个很好的资源

基本上,对于默认GC,有两种类型的运行:1)部分GC,其中年龄较小的对象被解除分配。 2)完整的GC,其中Garbage Colelction在所有对象上运行。

你能否提供带有参数的日志-XX:+ PrintGCDetails -XX:+ PrintGCTimeStamps。您的延迟可能是由于全GC,因为部分GC通常很容易损坏。如你所说,有很多可用的RAM,但是你可以指定分配的堆大小。它的所有损坏都是由于部分GC(概率很低),然后一次尝试用concurrenct标记和扫描使用+ UseConcMarkSweepGC,因为它是为部分GC中的高损耗定制的

答案 3 :(得分:2)

大多数Java垃圾收集器只能根据需要运行。一般来说,更多的内存导致更少的频繁,更长的垃圾收集.GC通常是懒惰的,这意味着它只会在堆处于最大大小时才开始真正尝试在内部回收内存。如果您没有设置上限,运行时将很乐意继续膨胀,直到它使用您系统上的每个可用内存位。

Sun JVM对其内存分配池(-Xmx)的大小使用固定的上限。您可以手动更改限制(参数-Xmx)

答案 4 :(得分:1)

可能是不同世代的大小不正确。

关于这一点的好文章是 http://java.sun.com/docs/hotspot/gc1.4.2/