Java Memory Origin Java内存区域 及分代GC

Java Memory Origin Java内存区域 及分代GC

[TOC]
Java Memory Origin 全称Java Runtime Memory Origin。
详细划分共五大区域:Method Area,Heap,VM Stack,Native Method Stack,Program Counter Register.
按照GC回收代,分为年轻代、老年代、HotSpot4Jdk7永久代/HotSpot4Jdk8的MetaSpace。
几种划分的对应图如下:


JVM详细分代分区划分对应图.jpg

还有一种比较粗糙的划分就是堆栈划分。

一、堆栈划分Heap & Stack

把Java内存分为堆内存和栈内存(Heap & Stack),的分法比较粗糙。但体现了大多数程序员最关注的、与对象内存分配最密切的内存区域是这两块。

  • 其中"栈"指的是五大分区中VM Stack中局部变量表部分。
  • "堆"指的是Heap

Stack 栈(私有)

栈的优势是

  • 存取速度比堆要快,仅次于直接位于CPU中的寄存器。

栈的缺点是

  • 栈数据在多个线程或者多个栈之间是不可以共享的(但是在栈内部多个值相等的变量是可以指向一个地址的)。
  • 存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

Heap 堆(共享)

堆的优势是

  • 数据可共享
  • 速度慢
  • 可以动态地分配内存大小,生存期也不必事先告诉编译器
  • Java的垃圾收集器会自动收走这些不再使用的数据。

堆的缺点是

  • 由于要在运行时动态分配内存,存取速度较慢。

二、五大内存区域划分:方法区、本地方法栈、程序计数器、栈、堆

Memory Origin Thread Private、Share
Method Area Share
Heap Share
VM Stack Private
Native Method Stack Private
Program Counter Register Private
JVMMemoryOrigin.png
  • JVM在执行Java程序的过程中,将它所管理的内存划分成五大区域,前两个是所有线程共享的数据区,后三个是隔离数据区。其中VM Stack\Program Counter Register是线程私有的。
  • 有的区域随着虚拟机进程的启动而存在,有的则依赖用户线程的启动结束而建立销毁。

1.Method Area 方法区

共享数据区,别名Non-Heap,永久代(HotSpot for Jdk8 已经移除)

  • jdk8以前,很多人称该区为"永久代"(Permanent Generation),仅仅是因为HotSpot把GC分代收集扩展至方法区,使用分代中的永久代来实现了方法区,hotSpot for Jdk8及以后及其他虚拟机不存在永久代的概念。
  • jdk8及以后hotSpot采用 Metaspace(动态调整大小,最大可达物理内存) 替代 PermGen(只能启动时指定,最大64M)来存储Method Area
  • 用来存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
  • 异常:OutOfMemoryError
1.1Runtime Constant Pool 运行时常量池

方法区的一部分,存放编译器生成的各种字面量和符号引用。

2.Heap 堆

共享数据区,线程共享。

  • 垃圾收集器管理的主要区域,也叫做GC堆(Garbage Collected Heap)。
  • 最大的一块内存;作用是存放对象实例,(几乎所有的对象实例都是这里分配,"几乎"是指新出的一些优化技术,比如逃逸分析)。
  • 可根据内存回收角度或者内存分配角度划分,无论如何划分都与存放内容无关,存储的都仍然是对象实例。进一步划分的目的是未来更好的回收内存,或者更快的分配内存。
  • 异常:OutOfMemoryError
  • 线程共享的Heap中可能分配多个线程私有的分配缓冲区Thread Local Allocation Buffer TLAB
  • 多线程内存分配的时涉及到线程安全的问题,一般有两种解决办法:1:加锁。2.TLAB,单个线程的预分配内存满了,才需要同步锁定。

3.VM Stack 虚拟机栈

隔离数据区,线程私有。
VM Stack记录的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame),用来存储局部变量表(堆栈分法的"栈"区域指的就是这块)、操作数栈、动态链接、方法出口等信息。
每个方法调用直至执行完成的过程就对应这一个栈帧在VM Stack中入栈到出栈的过程。

  • 异常:StackOverflowError & OutOfMemoryError
3.1局部变量表

局部变量表部分存放了

  • 编译期可知的8基本数据类型,64位的long,double会占据两个Slot局部变量空间。
  • 对象引用(reference类型,指向一个对象起始地址的引用指针、代表对象的句柄或其他与此对象相关的位置)。
  • returnAddress类型(指向一条字节码指令的地址)

局部变量表所需要的内存在编译期间确定。当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的。方法运行期间不会改变局部变量表的大小

4. Native Method Stack 本地方法栈

隔离数据区,线程私有,HotSpot的实现将之合并到了VM Stack.

  • 用户VM stack作用相似,不同的是VM stack为Java方法(也就是字节码)服务,Native Method Stack 为虚拟机使用到的Native方法服务。Native Method是非Java的方法实现,如对OS的一些调用,C++实现的一些外部方法。
  • 异常:StackOverflowError & OutOfMemoryError

5. Program Counter Register 程序计数器

隔离数据区,线程私有。
Program Counter Register是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。
分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
每个线程都需要一个独立的Program Counter Register,这类每个线程独立存储的内存区域被称为"线程私有"内存。

三、对象结构 Object Structure(JDK6实现)

Object存储在Heap中,hotSpot虚拟机中(jdk6或之前的图),其结构如下:


Java_Object_Structure_Hotspot.png

3.1 head 对象头

3.1.1 markWord

markWord,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32/64位的虚拟机(未开启压缩指针)中分别为32/64bit。

  • 最后2bit是锁状态标志位,在无锁和偏向锁两种状态下,2bit前的1bit标识是否偏向。
    markdown存储内容
状态 标志位 markWord存储内容
未锁定 01 对象哈希码、对象分代年龄
偏向锁 01 偏向线程ID、偏向时间戳、对象分代年龄
轻量级锁定 00 指向锁记录的指针
膨胀(重量级锁定) 10 执行重量级锁定的指针
GC标记 11 空(不需要记录信息)

具体的存储内容如下:


markWord_lock.jpg

无锁、偏向、轻量、重量几种级别的转换图如下:


sync锁级别转化.png
3.1.2 klass 类型指针

klass,类型指针,即对象指向它的类元数据的指针,hotSpot通过这个指针来确定当前对象是哪个类的实例。

3.2 instance data 对象实例数据

instance data 存储的是对象的有效信息,各种非静态的变量(实例变量),包括父类继承的实例变量。

3.2 padding 对齐

由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,没有对齐使用padding补齐。

四、逻辑按代划分

Heap分为Eden、Survivor、Old Gen;非Heap分为Code Cache、Perm Gen、Jvm Stack、Local Method Stack

jdk7中的永久带Perm Gen在jdk8中被元空间 MetaSpace取代,并从JVM虚拟内存中移动到本地内存(native heap memory)
官方的解释

In JDK 8, classes metadata is now stored in the native heap and this space is called Metaspace.

也就是说,JDK 8 开始把类的元数据放到本地堆内存(native heap)中,这一块区域就叫 Metaspace.

注意这里的native heap是堆结构的本地内存,注意与JVM中的Heap区分。

总结下,JVM按代划分为 年轻代(包括Eden、几级Survivor)、老年代(Old Gen)、jdk7的永久代(Perm Gen)/jdk8的位于本地内存中的元空间MetaSpace。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容