如何判断其中一个堆代是否已满?

时间:2012-11-23 09:02:42

标签: java memory garbage-collection jvm heap

我们在生产环境中遇到了一些问题,我们在一段时间后从一个已编译的jsps(其中一个不时有所不同)中获得InvalidPropertyException。我怀疑这是由堆中“消失”的东西引起的。此外,我怀疑这是由于堆中的一代变满了,所以有些对象会“溢出”到不同的一代,最终它会被GC编辑。

我想知道的是:是否有可能自动监控堆,并在其中一代已满并且有可能发生此类泄漏时发出警报?这可能是以编程方式或通过某种配置。我们已经尝试使用JConsole,但只有在错误开始发生后,然后一切看起来都没问题,但我真正想要的是知道它在确切时间的样子错误发生(或实际上几分钟前),无需手动监控。

我已针对此问题发布了一个更为一般性的问题,其中包含更多详细信息:Spring, NotReadablePropertyException and Glassfish version

2 个答案:

答案 0 :(得分:2)

我不是说你的问题与堆有关是不可能的,但是如果是这样的话,那就表明内存子系统和JVM中的垃圾收集器存在严重且非常严重的错误。虽然当然不是不可能的,但它是高度的,极不可能的,因为它肯定会被其他多个人发现,我没有听到其他人报告任何类似的事情。

基本上,对象永远不会GC:ed,但仍然至少有一个对象的实时引用。在堆中的代之间移动与它无关,这只是GC完成后台工作以优化内存处理。事实上,并非所有的JVM都有几代人。

如果您有“消失”的对象,则可能是因为您正在使用WeakReferenceSoftReference,或者因为您只是在代码中取消引用该对象,因此可以进行回收。

如果您发布有关实际异常(堆栈跟踪等)和相关代码的更多详细信息,也许这里有人可以帮助您找到问题。

答案 1 :(得分:0)

除了评论之外,如果您真的想看看不同代的情况,请打开详细GC记录。只需将-verbose:gc-XX:+PrintGCDetails添加到java命令即可。这将导致GC日志包含以下行:

94.198: [Full GC (System) 94.198: [Tenured: 788K->759K(4096K), 0.0428238 secs] 883K->759K(5056K), [Perm : 2095K->2095K(12288K)], 0.0429641 secs]

这告诉您垃圾收集之前和之后每代使用了多少空间。

This article也有很多关于此主题的信息,我从this blog获取了上述日志示例。