首先,Perm空间和Heap空间之间有什么区别(JVM选择如何以及如何选择使用每个内存空间)?
其次,但最重要的是,对于标准MVC类型的Java应用程序,建议采用哪种比率?
Answers:
该堆存储所有的Java程序创建的对象。堆的内容由垃圾收集器监控,当您停止使用对象时(即,当不再有对该对象的引用时),垃圾收集器会从堆中释放内存。
这与堆栈相反,堆栈存储原始类型(如ints和chars),并且通常是局部变量和函数返回值。这些不是垃圾收集。
该烫发空间是指堆的一个特殊部分。请参阅此SO答案以获取解释: 什么是烫发空间?
-XX:MaxPermSize=256m
以将烫发空间大小设置为256MB。
就个人而言,我不会将PermGen视为堆的特殊部分。
我更喜欢将堆视为专用于存储对象实例的内存区域,而将PermGen视为专用于存储类定义的区域。结果,堆的生命周期与应用程序相关,而PermGen的生命周期与JVM相关。
应用程序及其JVM具有不同生命周期的最佳示例之一是Java EE容器。在应用程序服务器中,可以在不重新启动服务器的情况下部署和取消部署应用程序。在取消部署(或重新部署)期间,释放所有对象实例(即堆空间)很容易,但是从PermGen清除此应用程序加载的所有类很棘手,因为JVM仍可以引用某些类。
这种情况之一就是泄漏驱动程序。部署应用程序后,将加载JDBC驱动程序并在DriverManager中注册。取消部署此应用程序时,DriverManager继续存在并保留对驱动程序,其原始类加载器以及该类加载器加载的所有内容的引用。结果,在PermGen中创建了内存泄漏,但这并不是应用程序的内存管理的错。
的确,像JRocket这样的JVM根本没有PermGen,所有内容都存储在堆中。只有在这种情况下,才能将PermGen称为堆的“特殊部分”。即使那样,我们仍然应该以不同的方式查看PermGen和堆,因为它们的用途非常不同,并且它们具有非常不同的内存泄漏类型。
更新:在Oracle的JDK 8中,PermGen被“ Metaspace”代替,现在正式成为堆的一部分。我们不再需要专门调整PermGen。