什么导致JVM执行主要垃圾回收? [英] What causes the JVM to do a major garbage collection?

查看:213
本文介绍了什么导致JVM执行主要垃圾回收?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java应用程序,它在不同的环境中显示不同的GC行为。在一个环境中,堆使用图是一个缓慢的锯齿,每10个小时左右有一个主要的GC,只有当堆大于90%满时。在另一个环境中,JVM每小时在这个点上执行主要的GC(在这些时间内堆一般在10%到30%之间)。



我的问题是,什么是什么原因导致JVM决定做一个重要的GC?



显然它会在堆满时收集,但还有其他一些原因,我猜测是与我的应用程序中的每小时计划任务有关(尽管此时内存使用量没有增加)。我假设GC行为在很大程度上取决于JVM ;我使用的是:


  • Java HotSpot™64位服务器虚拟机1.7.0_21 Oracle Corporation

  • 没有特定的GC选项,因此使用64位服务器的默认设置(PS MarkSweep和PS Scavenge)



其他信息:


  • 这是一个在Tomcat 6中运行的web应用程序。

  • 这两个环境。

  • 具有锯齿行为的环境具有7Gb最大堆,另一个具有14Gb。


    请不要猜测。 JVM必须有决定何时执行主要GC的规则,并且这些规则必须在源代码的某处进行深入编码。如果有人知道他们是什么,或他们在哪里被记录,请分享!

    解决方案

    垃圾收集是一个非常复杂的话题,虽然你可以了解这方面的所有细节,但我认为你案例中发生的事情很漂亮简单。



    Sun's 垃圾收集调整指南在显式垃圾收集标题下警告:


    应用程序可以进行交互使用垃圾回收......通过显式调用完整的垃圾回收......这可以强制主要回收在不必要的时候完成...... 显式垃圾回收最常见的用法之一是RMI ... RMI强制全部回收




    <该指南指出,垃圾收集之间的默认时间为1分钟,但 sun.rmi属性参考,位于 sun.rmi.dgc.server.gcInterval 中说:


    默认值为3600000毫秒(一小时)。


    如果您在一个应用程序中每小时查看主要集合,但不是另一个应用程序,这可能是因为应用程序正在使用RMI,可能只在内部使用,并且未将 -XX:+ DisableExplicitGC 添加到启动标志。



    禁用显式GC,或通过设置 -Dsun.rmi.dgc.server.gcInterval = 7200000 并观察GC是否每两小时发生一次。


    I have a Java app which shows different GC behaviour in different environments. In one environment, the heap usage graph is a slow sawtooth with major GCs every 10 hours or so, only when the heap is >90% full. In another environment, the JVM does major GCs every hour on the dot (the heap is normally between 10% and 30% at these times).

    My question is, what are the factors which cause the JVM to decide to do a major GC?

    Obviously it collects when the heap is nearly full, but there is some other cause at play which I am guessing is related to an hourly scheduled task within my app (although there is no spike in memory usage at this time).

    I assume GC behaviour depends heavily on the JVM; I am using:

    • Java HotSpot(TM) 64-Bit Server VM 1.7.0_21 Oracle Corporation
    • No specific GC options, so using the default settings for 64-bit server (PS MarkSweep and PS Scavenge)

    Other info:

    • This is a web app running in Tomcat 6.
    • Perm gen hovers around 10% in both environments.
    • The environment with the sawtooth behaviour has 7Gb max heap, the other has 14Gb.

    Please, no guesswork. The JVM must have rules for deciding when to perform a major GC, and these rules must be encoded deep in the source somewhere. If anyone knows what they are, or where they are documented, please share!

    解决方案

    Garbage collection is a pretty complicated topic, and while you could learn all the details about this, I think what’s happening in your case is pretty simple.

    Sun’s Garbage Collection Tuning guide, under the "Explicit Garbage Collection" heading, warns:

    applications can interact with garbage collection … by invoking full garbage collections explicitly … This can force a major collection to be done when it may not be necessary … One of the most commonly encountered uses of explicit garbage collection occurs with RMI … RMI forces full collections periodically

    That guide says that the default time between garbage collections is one minute, but the sun.rmi Properties reference, under sun.rmi.dgc.server.gcInterval says:

    The default value is 3600000 milliseconds (one hour).

    If you’re seeing major collections every hour in one application but not another, it’s probably because the application is using RMI, possibly only internally, and you haven’t added -XX:+DisableExplicitGC to the startup flags.

    Disable explicit GC, or test this hypothesis by setting -Dsun.rmi.dgc.server.gcInterval=7200000 and observing if GCs happen every two hours instead.

    这篇关于什么导致JVM执行主要垃圾回收?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆