【问题标题】:Adding java ClassLoaders to heap not perm gen将 java ClassLoaders 添加到堆而不是 perm gen
【发布时间】:2013-03-10 06:05:45
【问题描述】:

我们有一个应用程序可以生成数千个 Java 类加载器和类,然后再让它们被垃圾回收。我们很确定没有类加载器泄漏,但是我们遇到了 permgen 错误(即使有,这个问题也与任何潜在的泄漏无关)。

有没有办法指定某些 ClassLoader 及其加载的类放在堆中而不是 perm gen 中?

我们在 Linux 上使用 Oracle JDK Java 6。


编辑:看起来 Java 8 将不再有 PermGen。它将被 Metaspace 取代。

http://java.dzone.com/articles/java-8-permgen-metaspace

【问题讨论】:

    标签: java memory-management permgen


    【解决方案1】:

    当然,您会遇到 perm gen 错误——这是类加载器放置类的地方。你会期待什么?

    您可以将它们映射到字节缓冲区,就像 Java NIO 所做的那样,但它们不会放在堆上。

    在采取特别措施之前,您应该尝试增加您的烫发大小。您需要多少烫发空间?使用 Visual VM 对其进行分析并查看。

    【讨论】:

    • 谢谢。 “当然,你会遇到 perm gen 错误——这是类加载器放置类的地方。你会期待什么?”我知道这一点,这就是我问这个问题的原因。如果这些对象可以放在常规内存中,那么我们就不会出现 permgen 错误(我们可能会出现堆错误,这可能有助于解决我们的问题)。我们目前使用 385M 的 PermGen,我认为不再增加是个好主意。正如我所说,可能存在泄漏,过去几天我们一直在使用 Visual VM 和 YourKit 寻找它。如果我们有堆错误而不是 permgen,事情可能更容易追踪。
    • 并非如此。内存就是内存——细分为几代是 GC/内存模型设计选择。为什么增加它不是一个好主意?如果您有堆错误,那么增加堆是否同样是个坏主意?整个方法都是错误的。
    【解决方案2】:

    有没有办法指定某些 ClassLoader 及其加载的类放在堆中而不是 perm gen 中?

    AFAIK,没有办法做到这一点。 AFAIK,permgen 分配发生在 JVM 运行时的深处,你无法做到这一点。 (我不认为类加载器本身在 permgen 中。我认为它只是代表类及其代码的 JVM 内部数据结构。)

    如果您的应用程序真的必须以这种方式工作,我认为您别无选择,只能使 permgen 足够大。 (显然,您应该检查真正的问题不是 permgen 泄漏。)

    但是,如果您的应用程序的架构需要生成大量的类和类加载器,这让我感到震惊。我会看看它正在做的事情是否不能以其他方式完成。

    【讨论】:

    • 是的,应用程序的架构很奇怪。我很想以不同的方式重组事物,但这适用于需要运行数百个创建、编译、运行和销毁 grails 项目的测试的 grails-ide。 Grails 使用 Groovy,而 Groovy 使用自定义类加载器来加载和编译其脚本。谢谢你的建议。我们会继续寻找。
    • 听起来是时候抛弃 Grails 了。我不知道它这么糟糕。感谢您的提醒。
    • 该评论可能有误。从用户的角度来看,Grails 工作得很好。当您运行 grails 命令然后退出时,用于编译的自定义类加载器是有意义的。我们现在遇到的问题是我们的 IDE 测试套件中的 permgen 问题,因为我们需要在同一个进程中执行数百个命令。
    • @AndrewEisenberg - 好的......所以>>是
    猜你喜欢
    • 2021-04-21
    • 2013-05-15
    • 2016-09-10
    • 1970-01-01
    • 2017-11-04
    • 2015-02-05
    • 1970-01-01
    • 2011-07-02
    • 2014-03-12
    相关资源
    最近更新 更多