java内存池是如何划分的?

Dan*_*cco 216 java memory pool

我目前正在使用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”
Run Code Online (Sandbox Code Playgroud)

他们之间有什么区别?

dfa*_*dfa 317

堆内存

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

  • Eden Space:最初为大多数对象分配内存的池.

  • 幸存者空间:包含在伊甸园空间的垃圾收集中幸存下来的物体的池.

  • Tenured GenerationOld Gen:包含在幸存者空间中存在一段时间的物体的池.

非堆内存

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

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

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

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

  • 我不确定@dfa是否完全正确,因为Java虚拟机规范明确指出:"虽然方法区域在逻辑上是堆的一部分,但简单的实现可能选择不垃圾收集或压缩它."但是很明显jconsole将Code Cache和Permanent Generation显示为Non-Heap,这似乎与规范相矛盾.谁能提供更多关于这个矛盾的澄清? (4认同)
  • 这篇文章的主要内容是:http://docs.intergral.com/pages/viewpage.action?pageId = 22478944该文档包含了一些关于JVM的其他好信息,值得浏览 (2认同)

Pyt*_*ner 62

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

堆被分成几个不同的部分,称为代.随着对象在更多垃圾收集中存活,它们被提升为不同代.老一代人不经常收集垃圾.因为已经证明这些物体寿命更长,所以它们不太可能被垃圾收集.

首次构造对象时,它们将在Eden Space中分配.如果他们在垃圾收集中幸存下来,他们会被提升为幸存者空间,如果他们在那里居住的时间足够长,他们就会被分配到Tenured Generation.这一代垃圾收集频率低得多.

还有第四代,称为永久代,或PermGen.驻留在此处的对象不符合垃圾回收条件,并且通常包含JVM运行所必需的不可变状态,例如类定义和字符串常量池.请注意,PermGen空间计划从Java 8中删除,并将替换为名为Metaspace的新空间,该空间将保存在本机内存中.参考:http://www.programcreek.com/2013/04/jvm-run-time-data-areas/

在此输入图像描述 在此输入图像描述


小智 35

对于Java8,非堆区域不再包含PermGen,但Metaspace是Java8中的一个主要变化,它应该用java来消除内存不足错误,因为可以根据jvm对类数据所需的空间来增加元空间大小.


Rav*_*abu 19

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

对象驻留在称为堆的区域中.堆在JVM启动时创建,并且在应用程序运行时可能会增大或减小.当堆变满时,会收集垃圾.

在此输入图像描述

您可以在以下SE问题中找到有关Eden Space,Survivor Space,Tenured Space和Permanent Generation的更多详细信息:

年轻,终身和烫发一代

自Java 8发布以来,PermGen已被Metaspace取代.

关于你的疑问:

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

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