Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有办法知道哪些对象在“中”;旧的;堆面积_Java_Garbage Collection_Jvm_Heap - Fatal编程技术网

Java 有没有办法知道哪些对象在“中”;旧的;堆面积

Java 有没有办法知道哪些对象在“中”;旧的;堆面积,java,garbage-collection,jvm,heap,Java,Garbage Collection,Jvm,Heap,我有很长的GC循环。 通过检查,我看到堆的永久(旧)区域中有太多的对象。 知道哪些对象在堆的哪个区域有什么用处,或者知道关于这些对象的任何静态信息。 我正在使用Sun/Oracle HotSpot JVM(Java 6) 编辑:关于我的问题的更多细节: 我有一个很大的堆(32GB),即使旧堆区域只有30%已满,运行GC也会手动暂停15秒。我想知道哪些对象是保留在旧区域中的“幸存者”,以便知道要优化的对象创建。我不知道有任何工具/实用程序可用于当前一代JVM 但另一方面,我不认为这样的实用程序会有

我有很长的GC循环。 通过检查,我看到堆的永久(旧)区域中有太多的对象。 知道哪些对象在堆的哪个区域有什么用处,或者知道关于这些对象的任何静态信息。
我正在使用Sun/Oracle HotSpot JVM(Java 6)

编辑:关于我的问题的更多细节:

我有一个很大的堆(32GB),即使旧堆区域只有30%已满,运行GC也会手动暂停15秒。我想知道哪些对象是保留在旧区域中的“幸存者”,以便知道要优化的对象创建。

我不知道有任何工具/实用程序可用于当前一代JVM

但另一方面,我不认为这样的实用程序会有什么帮助

GC时间过长通常是因为堆太满。当堆接近100%满时,花费在GC中的时间会呈指数增长。在最坏的情况下,堆会完全填满,应用程序会得到一个
OutOfMemoryError
。有两种可能的解决方案:

  • 如果根本原因是堆太小(对于您的应用程序试图解决的问题的大小),那么要么增加堆大小,要么寻找减少应用程序工作集的方法;i、 e.计算期间需要“活动”的对象的数量/大小

  • 如果根本原因是内存泄漏,请查找并修复它

在这两种情况下,使用内存分析器将帮助您分析问题。但您不需要知道哪些对象在旧代中。这与问题的根本原因或问题的解决方案无关


我想知道哪些对象是保留在旧区域中的“幸存者”,以便知道要优化的对象创建

这开始变得更有意义了。听起来你需要找出哪些物体是长寿命的。。。而不是他们居住的具体空间。您可以使用
jhat
来比较堆快照序列。(可能有更好的办法……)

然而,我仍然不认为这种方法会有帮助。问题是一个完整的GC需要遍历所有可访问(硬、软、弱、幻影)对象。如果你有一个32Gb的堆已经满了30%,那么你仍然有很多对象需要标记/扫描/重新定位。我认为解决方案可能是使用并发收集器并对其进行调整,以便它能够跟上应用程序的对象分配速率

听起来您可能正直接从代码中调用
System.gc()
不要那样做调用
System.gc()
通常会导致JVM执行完整的垃圾收集。这肯定会让你停下来。最好让JVM决定何时运行收集器


最后,不清楚“优化对象创建”是什么意思。你的意思是降低对象创建率吗?或者您是否正在考虑其他方法来管理长寿命(缓存?)对象的保留?

我从未见过一种工具允许在给定的一代中“探索”对象

我习惯使用Netbeans分析器。它不能真正做到你所要求的,但它有一个工具,可以给你什么是错误的想法


使用探查器运行应用程序,选择
内存
,然后在
实时结果
中有一列
世代
它不会告诉您每个对象的生成,但会告诉您对象的数量。因此,如果数字大于1,则可能是在终身空间中(可能是在幸存者空间中),如果数字一直在增长,则会出现内存泄漏

我认为没有任何实用程序可以告诉您不同世代中的对象数量

  • 一种方法是可以使用jdk附带的
    jconsole
    。在jconsole的帮助下,您可以连接到您的应用程序并监视所有代,这里您可能会得到一些我不确定的数据
  • 另一种方法是,您可以使用
    jmap
    进行转储,然后使用eclipse
    MAT
    工具对其进行分析
  • 或者,您可以使用下面的
    JVM
    参数运行应用程序,并在日志中提供有关GC的信息
  • 使用JVM参数启用GC日志记录;下面是我使用的论点。(注意:每次VM启动时,都会重置指定为文件的日志文件。

    -verbose:gc-Xloggc:file


    我认为这可能会对您有所帮助。

    工具大象轨迹可以分析对象的创建和死亡。通过这一点,您可以了解哪些类型的对象比预期的存活时间更长,并且通过方法历史记录,可以获得准确的对象


    但是大堆意味着非常长的配置文件时间和非常大的配置文件文件。

    我只使用过,而且。我不记得其中任何一个可以列出终身对象。他们会给你一些终身领域的统计数据。所以我只推荐这篇文章和+1在这篇博客文章中你的整套JVM启动参数是什么se向遇到这个问题的人解释->但是…根据网站的说法,它不适用于Java 1.7和(大概)更高版本。在试图查找内存泄漏时,知道哪些对象位于旧区域不是很有帮助吗?因为长寿命(引用的对象)应该在那里,即使在完全gc之后也不清理,对吗?嗯……我不这么认为。如果有足够的对象搅动,那么长寿对象最终可能会被保留。但这是gc特有的行为。无论哪种方式,信息都不必或不足以确定对象是否泄漏。并且(AFAIK)无论如何,这些信息都是不可用的。所以你的想法是毫无意义的……除非你打算这么做