烫发空间与堆空间


79

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

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

Answers:


80

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

这与堆栈相反,堆栈存储原始类型(如ints和chars),并且通常是局部变量和函数返回值。这些不是垃圾收集。

烫发空间是指堆的一个特殊部分。请参阅此SO答案以获取解释: 什么是烫发空间?


1
您提供的链接显示为“堆的分段”-真的是“堆栈的特殊部分”吗?使其成为堆(甚至是某种静态数据段)的一部分,而不是仅仅不适合此类事务的堆栈,将更加有意义。
Sergei Tachenov 2011年

1
它是堆的特殊部分。在您发表评论之前,我确实编辑了我的答案,但无论如何我还是很欣赏的纠正:)
Olhovsky 2011年

1
关于第二个问题有什么建议吗?
Gareth

2
@Gareth:这不用担心。有些JVM甚至没有专用的内存部分来存放烫发空间。如果遇到java.lang.OutOfMemory异常,则可以直观地看到此工具使用了多少烫发空间:alphaworks.ibm.com/tech/pmat,然后,如果烫发空间不足(根据我的经验),您可以使用命令行选项增加烫发空间大小,-XX:MaxPermSize=256m以将烫发空间大小设置为256MB。
Olhovsky

1
好的我明白了。因此,实际上没有任何百分比规则或任何东西。谢谢。
Gareth

34

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

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

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

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

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

更新:在Oracle的JDK 8中,PermGen被“ Metaspace”代替,现在正式成为堆的一部分。我们不再需要专门调整PermGen。


0

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.