PermGen和堆,它们的区别及其重要性

15

朋友们,

你能否请告诉我堆(heap)和永久代(PermGen)的意义、区别和用途? 同时也希望了解它们分别加载了哪些类。

与Java虚拟机规范相关的解释将非常有帮助。

谢谢, Punith


请参考以下相关问题:https://dev59.com/xnI95IYBdhLWcg3w-DBb#33994430 - Ravindra babu
5个回答

22

内存(堆)按照不同年龄的对象被分配在不同的代或内存池中进行管理。当某个代填满时,它就会进行垃圾回收。对象被分配到年轻代或者young generation中用于存放年轻对象,因为大部分对象都是“早夭”的。

每当创建一个新的对象时,它都会被放入到Eden空间中,这是Young Generation的一部分。

如果对象在一段时间后仍然存活,则会被移到tenured generation,其中存放着长寿命的对象。

如果对象需要存活到整个进程结束,那么它将会被移动到Perm GenerationJava类存放在永久代中。


2

1
我对PermGen和其他堆内存部分也有同样的疑问。经过一番搜索,我得出了以下结论。
Java HotSpot VM需要从操作系统获取内存,这种内存被称为堆内存。现在,众所周知,堆内存用于存储对象,并且还保存着其他重要信息。
短生命周期的Java对象存储在年轻代中,如果这些对象仍然需要进一步执行,则会将其转移到老年代。根据不同类型的代垃圾回收器,内存会被清理。
那么永久代(PermGen)呢? Java HotSpot VM将类/类结构加载到PermGen中,该区域由JVM用于存储已加载的类和其他元数据。PermGen不用于存储对象。
除了对象和类结构之外,JVM代码本身还加载了分析器代理代码和数据等。
因此,基本上,堆=对象+类结构+JVM架构。
参考文献: Java Docs, Java GC Guide

0

我不是专家,但PermGem内存位于堆中,因为它是一个特殊的地方,在运行时加载所有类。因此,如果您有太多类,PermGem会抛出OutOfMemoryException。堆存储您在Java代码中实例化的对象,其中GC收集在堆栈中运行的线程中未被任何变量引用的对象。


2
这不是真的。PerGen与堆空间是分开的。请查看(此链接)[https://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation]。 - Santosh
是的,你说得对。我不确定我在哪里读到了相反的内容,但这确实有道理,因为他们分离它的目的是让GC不检查永久数据,所以它只检查堆中可以收集的“东西”。 - Ed Morales

0

我相信Permgen只是堆内存中的一个内存区域。它被创建出来是为了特殊目的,比如保存字符串。

并不是所有创建的对象都会占用Permgen内存,它只为JDK 6或更早版本中的特殊类(如String)所使用。

在现代的JDK版本中,如8及以上版本,已经没有Permgen了,但是引入了新的内存,如非堆内存和其他各种缓存内存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接