烫发空间 vs 堆空间
首先,彼尔姆空间和堆空间有什么区别(JVM选择使用每个内存空间是什么以及如何选择使用)?
其次,但最重要的是,对于标准的MVC类型的java应用程序,建议使用什么样的比率?
首先,彼尔姆空间和堆空间有什么区别(JVM选择使用每个内存空间是什么以及如何选择使用)?
其次,但最重要的是,对于标准的MVC类型的java应用程序,建议使用什么样的比率?
堆存储 Java 程序创建的所有对象。堆的内容由垃圾回收器监视,当您停止使用对象时(即,当没有更多对对象的引用时),垃圾回收器会从堆中释放内存。
这与堆栈相反,堆栈存储整数和字符等基元类型,并且通常是局部变量和函数返回值。这些不是垃圾回收。
烫发空间是指堆的特殊部分。请参阅此SO答案以获取解释:什么是烫发空间?
就个人而言,我不认为PermGen是堆的特殊部分。
我更愿意将堆视为专用于存储对象实例的内存区域,而PermGen则视为专用于存储类定义的区域。因此,堆的生命周期与应用程序相关联,而PermGen的生命周期与JVM相关联。
为什么应用程序及其 JVM 可以具有不同生命周期的最好示例之一是在 Java EE 容器中。在应用服务器中,无需重新启动服务器即可部署和取消部署应用程序。在取消部署(或重新部署)期间,很容易释放所有对象实例,即堆空间,但是从PermGen清除此应用程序加载的所有类是相当棘手的,因为某些类仍然可以被JVM引用。
其中一个案例是泄漏的驱动程序。部署应用时,将加载 JDBC 驱动程序并将其注册到驱动程序管理器。取消部署此应用时,DriverManager 将继续存在,并保留对驱动程序、其原始类装入器以及此类装入器加载的所有内容的引用。因此,在PermGen中创建了内存泄漏,但这不是应用程序内存管理的错误。
确实,像JRocket这样的JVM根本没有PermGen,一切都存储在堆中。只有在这样的上下文中,您才能将PermGen称为堆的“特殊部分”。即便如此,我们仍然应该以不同的方式看待PermGen和堆,因为它们具有非常不同的目的,并且它们具有非常不同类型的内存泄漏。
更新:在Oracle的JDK 8中,PermGen被“Metaspace”取代,现在正式成为堆的一部分。我们不再需要专门调整PermGen。