Java内存池是如何划分的?

w9apscun  于 2023-04-10  发布在  Java
关注(0)|答案(5)|浏览(120)

我目前正在使用jconsole监控一个Java应用程序。内存选项卡允许您选择:

Heap Memory Usage
Non-Heap Memory Usage
Memory Pool “Eden Space”
Memory Pool “Survivor Space”
Memory Pool “Tenured Gen”
Memory Pool “Code Cache”
Memory Pool “Perm Gen”

它们之间的区别是什么?

mccptt67

mccptt671#

堆内存

堆内存是运行时数据区域,Java VM从该区域为所有类示例和数组分配内存。堆的大小可以是固定的,也可以是可变的。垃圾收集器是一个自动内存管理系统,用于回收对象的堆内存。

  • [***]伊甸空间酒店:最初为大多数对象分配内存的池。
    *幸存者空间:包含Eden空间的垃圾回收后仍存在的对象的池。
    *终身世代老世代:包含在幸存者空间中已存在一段时间的对象的池。

非堆内存

非堆内存包括在Java VM的内部处理或优化所需的所有线程和内存之间共享的方法区域。它存储每个类的结构,例如运行时常量池,字段和方法数据,以及方法和构造函数的代码。方法区域在逻辑上是堆的一部分,但根据实现,Java VM可能不会对其进行垃圾收集或压缩。与堆内存一样,方法区可以是固定的或可变的大小,用于方法区的存储器不需要是连续的。

*永久生成:包含虚拟机本身所有反射数据的池,例如类和方法对象。对于使用类数据共享的Java VM,这一代被划分为只读和读写区域。
*代码缓存:HotSpot Java VM还包括一个代码缓存,其中包含用于编译和存储本机代码的内存。

Here's some documentation on how to use Jconsole

xxe27gdn

xxe27gdn2#

new关键字在Java堆上分配内存。堆是主内存池,可供整个应用程序访问。如果没有足够的内存可供分配给该对象,JVM将尝试使用垃圾回收从堆中回收一些内存。如果仍然无法获得足够的内存,则抛出OutOfMemoryError,JVM将退出。
堆被分成几个不同的部分,称为代。当对象在更多的垃圾收集中幸存下来时,它们被提升到不同的代。旧的代不经常被垃圾收集。因为这些对象已经被证明是更长的生命,所以它们不太可能被垃圾收集。
当对象第一次被构造时,它们被分配在伊甸园空间中。如果它们在垃圾收集中幸存下来,它们将被提升到幸存者空间,如果它们在那里存活足够长的时间,它们将被分配到终身世代。这一代的垃圾收集频率要低得多。
还有第四代,称为Permanent Generation,或PermGen。驻留在这里的对象没有资格被垃圾收集,并且通常包含JVM运行所需的不可变状态,例如类定义和String常量池。请注意,PermGen空间计划从Java 8中删除,并将被称为Metaspace的新空间取代。其将被保持在本机存储器中。参考:http://www.programcreek.com/2013/04/jvm-run-time-data-areas/

uinbv5nw

uinbv5nw3#

在Java8中,非堆区域不再包含PermGen,而是Metaspace,这是Java8中的一个主要变化,应该摆脱Java的内存不足错误,因为metaspace大小可以根据JVM对类数据所需的空间而增加。

b09cbbtk

b09cbbtk4#

Java堆内存是操作系统分配给JVM的部分内存。

对象驻留在一个称为堆的区域中。堆是在JVM启动时创建的,在应用程序运行时,堆的大小可能会增加或减少。当堆变满时,垃圾被收集。
关于伊甸园空间、幸存者空间、终身空间和永久世代的更多信息,请参见以下SE问题:
年轻、终身和烫发一代
自Java 8发布以来,PermGen已被Metaspace取代。
关于您的查询:

  1. Eden空间、Survivor空间、Tenured空间是堆内存的一部分
    1.元空间和代码缓存是非堆内存的一部分。

**Codecache:**Java虚拟机(JVM)生成本机代码,并将其存储在一个名为codecache的内存区域中。

7nbnzgx9

7nbnzgx95#

堆分为年轻代和老代,如下所示:

**年轻一代:**它是一个物体在短时间内居住的地方,它被分成两个空间:
***Eden Space:**使用new关键字创建对象时,在该空间上分配内存。
***Survivor Space(S0和S1):**这是一个池,其中包含从Eden空间进行小规模java垃圾收集后幸存的对象。
**老一代:**此池基本上包含终身和虚拟(保留)空间,并将保存那些在年轻一代垃圾收集后幸存的对象。
***Tenured Space:**该内存池中包含多次垃圾回收后存活的对象,即从Survivor空间回收垃圾后存活的对象。

说明

假设我们的应用程序刚刚开始。
所以在这一点上,所有这三个空间都是空的(Eden,S0,S1)。
每当创建一个新对象时,它都会被放置在Eden空间中。
当Eden空间被填满时,垃圾收集过程(次要GC)将在Eden空间上发生,并且任何幸存的对象都被移动到S0中。
然后我们的应用程序继续运行添加新的对象在Eden空间中创建垃圾收集过程下一次运行时它会查看Eden空间和S0中的所有内容并且任何幸存的对象都会被移动到S1中。
PS:根据Survivor空间中对象应该存活多少时间的配置,对象也可以来回移动到S0和S1,然后达到阈值的对象将被移动到旧代堆空间。

相关问题