简体   繁体   English

烫发空间与堆空间

[英]Perm space vs Heap space

First, What is the difference between Perm space and Heap space (What and how does the JVM choose to use each memory space)? 首先,Perm空间和堆空间之间有什么区别(JVM选择使用每个内存空间的内容和方式)?

Second, but most importantly, what sort of ratio would be recommended for a standard MVC type java application? 其次,但最重要的是,对于标准MVC类型的Java应用程序,建议使用什么样的比率?

The heap stores all of the objects created by your Java program. 存储Java程序创建的所有对象。 The heap's contents is monitored by the garbage collector, which frees memory from the heap when you stop using an object (ie when there are no more references to the object. 堆的内容由垃圾收集器监视,当您停止使用对象时(即,当没有对该对象的引用时),它会从堆中释放内存。

This is in contrast with the stack , which stores primitive types like ints and chars, and are typically local variables and function return values. 这与堆栈形成对比, 堆栈存储诸如整数和字符之类的基本类型,并且通常是局部变量和函数返回值。 These are not garbage collected. 这些不是垃圾收集。

The perm space refers to a special part of the heap. 烫发空间指的是堆的特殊部分。 See this SO answer for an explanation: What is perm space? 请参阅此SO答案以获得解释: 什么是烫发空间?

Personally, I wouldn't consider PermGen a special part of the heap. 就个人而言,我不认为PermGen是堆的特殊部分。

I'd much prefer to think of heap as a memory area dedicated to store object instances while PermGen as an area dedicated to store class definitions. 我更倾向于将堆视为专用于存储对象实例的内存区域,而将PermGen视为专用于存储类定义的区域。 As a result, a heap's lifecycle is tied to an application while PermGen's lifecycle is tied to a JVM. 因此,堆的生命周期与应用程序相关联,而PermGen的生命周期与JVM相关联。

One of the best examples why an application and its JVM can have different lifecycle is in a Java EE container. 应用程序及其JVM可以具有不同生命周期的最佳示例之一是Java EE容器。 In an app server, applications can be deployed and undeployed without restarting the server. 在应用程序服务器中,可以在不重新启动服务器的情况下部署和取消部署应用程序。 During the undeployment (or redeployment), it's easy to release all the object instances ie heap space, but it's rather tricky to clear all the classes loaded by this app from PermGen because some of the classes can still be referenced by the JVM. 在取消部署(或重新部署)期间,很容易释放所有对象实例,即堆空间,但是清除此应用程序从PermGen加载的所有类是相当棘手的,因为JVM仍然可以引用某些类。

One of such case is the Leaking Drivers . 其中一个例子就是泄漏的驱动因素 When an app is deployed, a JDBC driver is loaded and registered with the DriverManager. 部署应用程序时,将加载JDBC驱动程序并使用DriverManager注册。 When this app is undeployed, the DriverManager lives on and holds a reference to the driver, its original class loader, and everything this class loader loaded. 取消部署此应用程序时,DriverManager会继续存在并保存对驱动程序,其原始类加载器以及此类加载器加载的所有内容的引用。 As a result, a memory leak in PermGen is created, but it's no fault of the application's memory management. 结果,创建了PermGen中的内存泄漏,但这不是应用程序内存管理的错误。

It's true that JVMs like JRocket don't have PermGen at all, everything is stored in heap. 确实像JRocket这样的JVM根本没有PermGen,所有内容都存储在堆中。 Only in such context can you call PermGen a "special part" of heap. 只有在这种情况下才能将PermGen称为堆的“特殊部分”。 Even then, we should still view PermGen and heap differently since they have very different purpose and they have very different types of memory leaks. 即便如此,我们仍然应该以不同的方式查看PermGen和堆,因为它们具有非常不同的目的,并且它们具有非常不同类型的内存泄漏。

Update : In Oracle's JDK 8, PermGen is replaced by "Metaspace" and it is now officially part of the heap. 更新 :在Oracle的JDK 8中,PermGen被“Metaspace”取代,现在它正式成为堆的一部分。 We won't need to specifically tune PermGen any more. 我们不再需要专门调整PermGen了。

You can NOT give names to allocated memory in the heap. 您不能为堆中的已分配内存指定名称。

That means int x (its name) is allocated in the stack. 这意味着int x (它的名字)在堆栈中分配。 You can reach the pointer by its name, so the pointer is in the stack. 您可以通过其名称到达指针,因此指针位于堆栈中。 You can't reach the object by its name, cause it has no name. 您无法通过名称访问该对象,因为它没有名称。 Accees to the (nameless) object must be by its pointer. 对(无名)对象的接受必须是其指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM