Perm 空间与堆空间

首先,Perm 空间和 Heap 空间之间的区别是什么(JVM 选择使用哪些内存空间以及如何使用这些内存空间) ?

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

76638 次浏览

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

这与 形成对比,存储 int 和 char 等基本类型,通常是局部变量和函数返回值。这些不是垃圾回收。

烫发空间指的是堆中的一个特殊部分。参见下面的答案以获得解释: 什么是烫发空间?

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

我更倾向于将堆看作是专门用于存储对象实例的内存区域,而将 PermGen 看作是专门用于存储类定义的区域。因此,堆的生命周期绑定到应用程序,而 PermGen 的生命周期绑定到 JVM。

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

其中一个例子就是 漏油的司机。部署应用程序时,将加载 JDBC 驱动程序并在 DriverManager 中注册。当这个应用程序被卸载时,DriverManager 继续存在并保存对驱动程序、其原始类加载器以及这个类加载器加载的所有内容的引用。因此,在 PermGen 会出现内存泄漏,但这并不是应用程序内存管理的错误。

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

更新 : 在 Oracle 的 JDK 8中,PermGen 是 取而代之的是“元空间”,现在它正式成为堆的一部分。我们不再需要专门调整 PermGen。

不能为堆中分配的内存提供名称。

这意味着在堆栈中分配了 int x(它的名称)。可以通过指针的名称到达指针,因此指针位于堆栈中。你不能通过对象的名字到达它,因为它没有名字。对(无名)对象的访问权限必须通过其指针。