Jvm笔记-01-Java运行时数据区域与对象

运行时数据区域

1. 程序计数器 Program Counter Register

通过改变计数器值选取下一条指令完成分支、循环、跳转、异常处理、线程恢复等基础功能。
线程私有,互不影响。

2. Java虚拟机栈 JVM Stacks

线程私有,生命周期与线程相同。
每个方法执行时创建栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等,方法调用与完成对应入栈和出栈。
Java内存区粗略分为堆和栈,栈即虚拟机栈。
配置 -Xss 参数设定栈帧大小

3. 本地方法栈 Native Method Stack

执行本地方法的栈。

4. Java堆 Java Heap

线程共享,虚拟机启动时创建,几乎所有对象在这里分配内存。
Java堆分为新生代(EdenFrom SurvivorTo Survivor)和老年代。
-Xms 最小值,-Xmx 最大值

5. 方法区 Method Area

线程共享,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。
被成为永久代 Permanent Generation,配置 -XX:MaxPermSize 上限。

6. 运行时常量池 Runtime Constant Pool

运行时常量池是方法区中一部分,jdk8被放到 MetaSpace 空间。
类的版本、字段、方法、接口等描述信息,还有常量池(Constant Pool Table ),存放编译期生成的各种字面量和符号引用。
jdk7之前,字符串常量池在方法区中,使用 String.intern() 方法可将字符串放入。

7. 直接内存 Direct Memory

不是虚拟机运行时数据区的一部分,也可能OOM异常。
jdk1.4加入NIO,是一种基于通道 Channel 和缓冲区 Buffer 的I/O方式,可以使用 Native 函数库直接分配对外内存,然后通过堆中 DirectByteBuffer 对象作为这块内存的引用进行操作,避免Java堆与Native堆中数据复制来提高效率。

对象

对象的创建

  1. 遇到new指令时,首先检查指令参数能否在常量池中定位到一个类的符号引用,并检查这个这个符号引用代表的类是否被加载、解析和初始化过。

  2. 如果没有,执行相应的类加载过程。

  3. 类加载通过后,虚拟机为新生对象分配内存。

     如何分配内存?
     对象所需内存大小在加载完成后便完全确定,所以将一块确定大小内存从Java堆中划分出来即可。  
     若内存规整,采用指针碰撞分配算法,将指针向空闲空间挪动。
     若非连续存放,须维护空闲列表,找到足够大空间划分。
     `Serial` 串行收集器、`ParNew` 多线程串行收集器等带 `Compact` 过程收集器,分配算法采用指针碰撞。
     `CMS` 这种基于 `Mark-Sweep` 算法,采用空闲列表。
    
  4. 内存分配完成后,将分配到的内存空间初始化为零值。

  5. 虚拟机对对象进行必要设置,该实例所属类、类的元数据信息、对象哈希姆、对象GC分代年龄信息等,存放在对象头中。

  6. 执行 <init> 构造方法,按照程序员的意愿进行初始化,对象引用入栈。

对象的内存布局

对象在内存中存储布局分为 3 块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

  1. 对象头包括两部分信息

    第一部分是存储对象自身的运行时数据 Mark Word

     如哈希码、GC分代年龄、锁状态标识、线程持有锁、偏向线程ID、偏向时间戳等。
    

    另一部分是类型指针,即对象指向它的元数据的指针。

     虚拟机通过这个指针来确定该对象是那个类的实例。
    
  2. 实例数据

     对象真正存储的有效信息,即代码中定义的各类型字段内容。
    
  3. 对齐填充

     仅是占位符作用。
    

对象的访问定位

通过栈上的引用 reference 来操作堆上具体对象,主流的访问方式有使用句柄和直接指针两种。

  1. 句柄访问。

     Java堆中将划分出句柄池,'reference' 指向句柄地址,句柄中存放了对象实例数据与类型数据各自的具体地址信息。  
     优势:在对象被移动时只会改变句柄中实例数据指针,reference本身不需要修改。
    
  2. 直接指针访问。

     'reference' 直接存储对象地址,Java堆中对象布局中须防止访问类型数据信息。
     优势: 访问速度快,因节省了一次指针定位的时间开销。
     HotSpot使用直接指针进行对象访问。
    
posted @ 2018-01-18 08:34  张狂莫怪  Views(176)  Comments(0Edit  收藏  举报