java内存池如何划分?

我目前正在用jconsole监控一个Java应用程序。 内存选项卡让您select:

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” 

他们有什么区别?

堆内存

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

  • 伊甸园空间 :最初为大多数物体分配内存的池。

  • 幸存者空间(Survivor Space) :含有在伊甸园空间的垃圾收集中存活的对象的池。

  • Tenured Generation :含有在遗属空间中存在一段时间的物体的池。

非堆内存

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

  • 永久生成 :包含虚拟机本身的所有reflection数据的池,例如类和方法对象。 使用类数据共享的Java虚拟机,这一代分为只读和读写区域。

  • 代码caching :HotSpot Java VM还包含代码caching,其中包含用于编译和存储本机代码的内存。

这里有一些关于如何使用Jconsole的文档 。

新的关键字在Java堆上分配内存。 堆是整个应用程序可以访问的主要内存池。 如果没有足够的内存可用于为该对象分配内存,则JVM尝试从垃圾回收堆中回收一些内存。 如果仍然无法获得足够的内存,则会抛出OutOfMemoryError,然后JVM退出。

堆被分成几个不同的部分,称为世代。 随着对象生存更多的垃圾收集,他们被提升到不同的世代。 老一代不是经常收集垃圾。 因为这些物体已经被certificate是更长寿的,所以不太可能被垃圾收集。

当物体首先被build造时,它们被分配到伊甸园空间。 如果他们在垃圾收集中生存下来,他们将被提升到幸存者空间,如果他们能够在那里生存足够长的时间,他们将被分配给老一代。 这一代是垃圾收集less得多。

也有第四代,称为永久代,或PermGen。 这里驻留的对象没有资格被垃圾回收,并且通常包含JVM运行所必需的不可变状态,例如类定义和String常量池。 请注意,PermGen空间计划从Java 8中删除,并将被replace为一个名为Metaspace的新空间,该空间将保存在本机内存中。 参考: http : //www.programcreek.com/2013/04/jvm-run-time-data-areas/

在这里输入图像描述 在这里输入图像描述

在Java8中,非堆区域不再包含PermGen,但是Metaspace是Java8中的一个重大改变,应该可以根据jvm对类数据所需的空间来增加Java的内存错误。

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

对象驻留在一个称为堆的区域中。 堆是在JVM启动时创build的,并且在应用程序运行时可能会增加或减less。 当堆满时,垃圾被收集。

在这里输入图像描述

您可以在SE问题中find有关伊甸园空间,幸存空间,终身空间和永久代的更多详情:

年轻,终身和烫发一代

自Java 8发布以来,PermGen已经被Metaspace所取代。

关于你的查询:

  1. 伊甸园空间,幸存者空间,终身空间是堆内存的一部分
  2. Metaspace和Code Cache是​​非堆内存的一部分。

Codecache: Java虚拟机(JVM)生成本地代码并将其存储在称为codecache的内存区域中。 JVM由于多种原因生成本地代码,包括dynamic生成的解释器循环,Java本地接口(JNI)存根以及由即时(JIT)编译器编译为本机代码的Java方法。 JIT是迄今为止最大的codecache用户。