烫发空间与堆空间

Gar*_*eth 78 java performance memory-management

首先,Perm空间和堆空间之间有什么区别(JVM选择使用每个内存空间的内容和方式)?

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

Olh*_*sky 76

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

这与堆栈形成对比,堆栈存储诸如整数和字符之类的基本类型,并且通常是局部变量和函数返回值.这些不是垃圾收集.

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

  • @Gareth:这不是什么值得担心的事情.有些JVM甚至没有为perm空间提供专用的内存部分.如果你得到一个java.lang.OutOfMemory异常,那么可视化这个工具使用了多少perm空间:http://www.alphaworks.ibm.com/tech/pmat,然后如果你没有烫发空间(罕见)根据我的经验,您可以使用命令行选项`-XX:MaxPermSize = 256m`来增加perm空间大小,以将perm空间大小设置为256MB. (2认同)

Chr*_*ang 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了.