我目前在使用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”
它们之间有什么区别?
我目前在使用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”
它们之间有什么区别?
堆内存是Java虚拟机运行时数据区,用于为所有类实例和数组分配内存。堆可以是固定大小或可变大小。垃圾回收器是自动内存管理系统,用于回收对象的堆内存。
Eden空间:大部分对象最初分配内存的池。
Survivor空间:包含在Eden空间垃圾回收后幸存下来的对象。
老年代 或 Old Gen:包含已在Survivor空间存活一段时间的对象。
非堆内存包括共享于所有线程的方法区和Java虚拟机内部处理或优化所需的内存。它存储每个类的结构,例如运行时常量池、字段和方法数据以及方法和构造函数的代码。方法区在逻辑上是堆的一部分,但根据实现,Java虚拟机可能不会对其进行垃圾回收或压缩。与堆内存一样,方法区的大小可以是固定或可变的。方法区的内存不需要连续。
永久代:包含虚拟机本身的所有反射数据,例如类和方法对象。对于使用类数据共享的Java虚拟机,此代被分为只读区域和可读写区域。
代码缓存:HotSpot Java虚拟机还包括一个代码缓存,其中包含用于编译和存储本地代码的内存。
new
关键字在Java堆上分配内存。堆是主要的内存池,可供整个应用程序访问。如果没有足够的内存可用于分配该对象,则JVM尝试从堆中回收一些内存进行垃圾回收。如果仍然无法获得足够的内存,则会抛出OutOfMemoryError
错误,并退出JVM。-XX:PermSize
而不是-XX:MaxPermSize
,因为它已经在上面定义过了。 - Anurag在Java8中,非堆区不再包含PermGen而是Metaspace,这是Java8的重大变化,旨在通过增加元空间的大小(取决于JVM为类数据所需的空间)来消除Java内存不足错误。
Java Heap Memory(Java堆内存)是操作系统分配给JVM的一部分内存。
对象驻留在称为堆的区域中。堆在JVM启动时创建,应用程序运行时可能会增加或减小。当堆变满时,垃圾将被收集。
您可以在下面的SE问题中找到有关 Eden Space、Survivor Space、Tenured Space和Permanent Generation 的更多详细信息:
Young , Tenured and Perm generation
自Java 8版本以来,PermGen已被Metaspace所取代。
关于您的查询:
Codecache:JVM生成本地代码并将其存储在称为codecache的内存区域中。 JVM出于各种原因生成本地代码,包括针对动态生成的解释器循环,Java Native Interface(JNI)存根以及通过即时(JIT)编译器将Java方法编译为本地代码。 JIT是codecache的最大使用者。
说明
假设我们的应用程序刚刚启动。
因此,此时这三个空间(Eden、S0、S1)都是空的。
每当创建新对象时,它都会被放置在Eden空间中。
当Eden空间变满时,垃圾回收过程(minor GC)将在Eden空间上进行,并将任何幸存的对象移动到S0中。
然后我们的应用程序继续运行,添加新对象时会在Eden空间中创建。下一次垃圾回收过程运行时,它会查看Eden空间和S0中的所有内容,并将幸存的对象移动到S1中。
PS:根据配置,对象在Survivor空间中应存活多长时间,对象可能也会在S0和S1之间来回移动。当达到阈值时,对象将移动到旧的生成堆空间。