【问题标题】:Perm space vs Heap space永久空间与堆空间
【发布时间】:2011-06-18 10:23:40
【问题描述】:

首先,Perm空间和Heap空间有什么区别(JVM选择什么以及如何使用每个内存空间)?

其次,但最重要的是,对于标准 MVC 类型的 Java 应用程序,建议采用什么样的比率?

【问题讨论】:

    标签: java performance memory-management


    【解决方案1】:

    你不能给堆中分配的内存命名。

    这意味着 int x(它的名字)在堆栈中分配。您可以通过其名称访问指针,因此指针位于堆栈中。您无法通过其名称访问该对象,因为它没有名称。访问(无名)对象必须通过其指针。

    【讨论】:

      【解决方案2】:

      就个人而言,我不会认为 PermGen 是堆的特殊部分。

      我更愿意将堆视为专用于存储对象实例的内存区域,而将 PermGen 视为专用于存储类定义的区域。因此,堆的生命周期与应用程序相关联,而 PermGen 的生命周期与 JVM 相关联。

      为什么应用程序及其 JVM 可以具有不同的生命周期的最佳示例之一是在 Java EE 容器中。在应用服务器中,无需重新启动服务器即可部署和取消部署应用程序。在取消部署(或重新部署)期间,释放所有对象实例(即堆空间)很容易,但是从 PermGen 中清除此应用程序加载的所有类则相当棘手,因为其中一些类仍然可以被 JVM 引用。

      这种情况之一是Leaking Drivers。部署应用程序时,会加载 JDBC 驱动程序并在 DriverManager 中注册。当这个应用程序被取消部署时,DriverManager 继续存在并持有对驱动程序、其原始类加载器以及该类加载器加载的所有内容的引用。结果,在 PermGen 中创建了内存泄漏,但这不是应用程序的内存管理的错误。

      确实像JRocket这样的JVM根本没有PermGen,一切都存储在堆中。只有在这种情况下,您才能将 PermGen 称为堆的“特殊部分”。即便如此,我们仍然应该以不同的方式看待 PermGen 和堆,因为它们的用途非常不同,并且它们具有非常不同类型的内存泄漏。

      更新:在 Oracle 的 JDK 8 中,PermGen 是 replaced by "Metaspace",它现在正式成为堆的一部分。我们不再需要专门调整 PermGen。

      【讨论】:

        【解决方案3】:

        存储您的 Java 程序创建的所有对象。堆的内容由垃圾收集器监控,当您停止使用对象时(即不再引用该对象时),它会从堆中释放内存。

        这与 stack 不同,后者存储原始类型,如 int 和 chars,通常是局部变量和函数返回值。这些不是垃圾收集。

        永久空间指的是堆的特殊部分。请参阅此 SO 答案以获取解释: What is perm space?

        【讨论】:

        • 您提供的链接说“堆的段” - 那么它真的是“堆栈的特殊部分”吗?将它作为堆的一部分(甚至是某种静态数据段)而不是不适合这种事情的堆栈会更有意义。
        • 它是堆的特殊部分。在您发表评论之前,我确实编辑了我的答案,但无论如何我感谢您的更正:)
        • 对第二个问题有什么建议吗?
        • @Gareth:这没什么好担心的。一些 JVM 甚至没有专门用于 perm 空间的内存部分。如果你得到一个 java.lang.OutOfMemory 异常,然后可视化这个工具使用了多少永久空间:alphaworks.ibm.com/tech/pmat,然后如果你没有永久空间(在我的经验中很少见)你可以增加永久空间大小命令行选项-XX:MaxPermSize=256m 将永久空间大小设置为256MB。
        • 好的,我明白了。所以真的没有任何百分比规则或任何东西。谢谢。
        猜你喜欢
        • 2011-10-11
        • 2011-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-11
        • 2021-09-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多