我如何发现永久世代中的东西

时间:2008-10-11 18:14:07

标签: java memory garbage-collection permgen permanent-generation

鉴于堆转储或正在运行的VM,我如何发现永久代的内容是什么?我知道'jmap -permstat',但这在Windows上不可用。

8 个答案:

答案 0 :(得分:1)

永久代包含类对象。 因此,您应该检查堆转储或其他形式的对象列表。 如果你对永久代的大小有问题,通常是由两个原因引起的:

  • 您使用的程序或库动态创建类,永久生成的默认大小太小 - 使用-XX简单地增加大小:MaxPermSize = 256m
  • 您的程序或您使用的库每次调用时都会动态创建新类,因此永久生成的大小会不停增加 - 这是一个编程错误,您应该修复它(或搜索修复/创建错误报告) )

要查看您的情况,请在更长的时间内检查永久代的大小。

关于永久性发电的一个很好的概述:

http://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation

答案 1 :(得分:1)

本文Memory Monitoring with Java SE 5介绍了如何以编程方式发现有关堆使用情况,内存池(包括permgen空间)等的信息。它非常简单:

    MemoryUsage usage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
    long nonHeapFree = usage.getMax() - usage.getUsed();
    long nonHeapTotal = usage.getMax();

在我对OSX(Sun VM)的测试中,“非堆内存使用”与permgen池返回的值相匹配,并且可能会对没有permgen的VM执行一些有用的操作。

答案 2 :(得分:0)

请参阅我的博客文章thr permsize of Eclipse

简而言之,Memory Analyzer可以运行,但您需要SAP JVM。

答案 3 :(得分:0)

您有具体问题需要解决吗? String.intern()的使用是permgen问题的典型原因之一。此外,有很多课程的项目也存在permgen问题。

我不知道如何进入permgen,看看它在那里......

答案 4 :(得分:0)

永久生成实际上只包含两种内容:类定义和实习字符串。后来很少给你带来问题,但它常常被归咎于问题。由于代码生成和部分热重新加载(悬空引用),前者更常出现问题。

与名称不同,permgen最终也会得到GC,而不是常规GC循环的一部分。因此,未引用的实习字符串和未使用的类确实得到清理。 但是permgen也没有动态增长,这意味着有时需要手动调整其JVM启动的设置。

答案 5 :(得分:0)

我正在研究同样的事情,但是由于嵌入式平台的内存限制。

查看jmap的代码,permstat工具仅在sun.jvm.hotspot.tools.HeapSummary类可用时才可用。此类是可维护性代理的一部分。根据OpenJDK文档(http://openjdk.java.net/groups/serviceability/svcjdk.html#bsa):

可维护性代理组件是作为HotSpot存储库的标准版本的一部分构建的。这些组件是:

-libsaproc.so:这是SA的本机代码组件。

-sa-jdi.jar:这包含SA的Java类。它包括一个JDI实现,它允许JDI客户端对核心文件和挂起进程进行只读调试。

SA由jinfo,jmap,jstack

使用

注意:可维护性代理及其使用的技术当前未包含在Windows平台上的JDK版本中。

同样也是Oracle JDK的情况。我正在修改jmap工具以获取更多信息。

答案 6 :(得分:0)

帮助我的一种技术是使用-verbose:class command-line option to java,并且您将获得日志输出,告诉您类的加载/卸载。由于类被加载到permgen,这在某些情况下会有所帮助。

答案 7 :(得分:-1)

您可以使用JConsole或jvisualvm.exe(使用jdk 1.6 7)查找其中的内容。如果您想知道所有对象如何相互关联以及对象树,那么您可能想要尝试Eclipse Memory Analyzer - http://www.eclipse.org/mat/

总之,你会想要“http://www.eclipse.org/mat/”。

祝你好运,