【发布时间】:2011-06-18 10:23:40
【问题描述】:
首先,Perm空间和Heap空间有什么区别(JVM选择什么以及如何使用每个内存空间)?
其次,但最重要的是,对于标准 MVC 类型的 Java 应用程序,建议采用什么样的比率?
【问题讨论】:
标签: java performance memory-management
首先,Perm空间和Heap空间有什么区别(JVM选择什么以及如何使用每个内存空间)?
其次,但最重要的是,对于标准 MVC 类型的 Java 应用程序,建议采用什么样的比率?
【问题讨论】:
标签: java performance memory-management
你不能给堆中分配的内存命名。
这意味着 int x(它的名字)在堆栈中分配。您可以通过其名称访问指针,因此指针位于堆栈中。您无法通过其名称访问该对象,因为它没有名称。访问(无名)对象必须通过其指针。
【讨论】:
就个人而言,我不会认为 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。
【讨论】:
堆 存储您的 Java 程序创建的所有对象。堆的内容由垃圾收集器监控,当您停止使用对象时(即不再引用该对象时),它会从堆中释放内存。
这与 stack 不同,后者存储原始类型,如 int 和 chars,通常是局部变量和函数返回值。这些不是垃圾收集。
永久空间指的是堆的特殊部分。请参阅此 SO 答案以获取解释: What is perm space?
【讨论】:
-XX:MaxPermSize=256m 将永久空间大小设置为256MB。