首先,Perm空间和堆空间之间有什么区别(JVM选择使用每个内存空间的内容和方式)?
其次,但最重要的是,对于标准MVC类型的Java应用程序,建议采用什么样的比率?
答案 0 :(得分:76)
堆存储Java程序创建的所有对象。堆的内容由垃圾收集器监视,当您停止使用对象时(即,当没有对该对象的引用时),它会从堆中释放内存。
这与堆栈形成对比,堆栈存储基本类型(如整数和字符),通常是局部变量和函数返回值。这些不是垃圾收集。
烫发空间是指堆的特殊部分。请参阅此SO答案以获得解释: What is perm space?
答案 1 :(得分:34)
就个人而言,我不认为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了。
答案 2 :(得分:0)
您不能为堆中的已分配内存指定名称。
这意味着int x
(其名称)在堆栈中分配。您可以通过其名称到达指针,因此指针位于堆栈中。您无法通过其名称访问该对象,因为它没有名称。对(无名)对象的接受必须是其指针。