JVM内存区域介绍

Java将内存控制权利交给Java虚拟机,其在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。

1. JDK1.7 VS JDK1.8

需要注意的是,相较于JDK1.8之前的版本,JDK1.8 中PermGen(永久代) 被 Metaspace(元空间) 取代,并且元空间使用的是本地内存。

2. 线程私有部分
作用内存溢出
虚拟机栈调用方法创建栈帧,方法结束则弹出栈帧不允许栈内存动态扩展,则可能出现OutOfMemoryError,若允许,则在动态扩展栈时无法申请到足够的内存空间时出现OutOfMemoryError
本地方法栈作用与虚拟机栈类似,为虚拟机使用的native方法服务与虚拟机栈一样,可能出现 StackOverFlowError 和 OutOfMemoryError 两种错误
程序计数器实现代码的流程控制,保证线程切换后能恢复到正确的执行位置不存在
3. 栈帧

栈由一个个栈帧组成,而每个栈帧中都拥有局部变量表、操作数栈、动态链接、方法返回地址。

作用
局部变量表存放编译器可知的基本数据类型以及对象引用
操作数栈存放中间计算结果以及计算过程中产生的临时变量
动态链接当一个方法要调用其他方法,其将指向该方法的符号引用转化为内存地址的直接引用
方法返回地址存放被调用方法的返回地址,该返回地址是一个具体数值
4. 线程共享部分
4.1 堆

堆是Java 虚拟机所管理的内存中最大的一块,也是垃圾收集器管理的主要区域,用于存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。为什么说是几乎呢?随着 JIT 编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术导致并非所有的对象都分配到堆上。

 

 JDK1.7堆空间 VS JDK1.8

4.2 方法区 

方法区和永久代以及元空间是什么关系呢?

 永久代以及元空间是 HotSpot 虚拟机对虚拟机规范中方法区的两种实现方式。永久代是 JDK 1.8 之前的方法区实现,JDK 1.8 及以后方法区的实现变成了元空间。

为什么要将永久代 (PermGen) 替换为元空间 (MetaSpace) 呢?

  1. 永久代受 JVM 空间大小限制,无法进行调整,而元空间使用的是本地内存,内存溢出几率更小
  2. 能加载的类更多
  3. 在 JDK8合并 HotSpot 和 JRockit 的代码时, JRockit 没有永久代这一说法
 5. 运行时常量池
  1. 存放编译期生成的各种字面量和符号引用的 常量池表(符号引用与直接应用一一对应) 
  2. 常量池表在类加载后存放到方法区的运行时常量池中
6.字符串常量池 

 HotSpot 虚拟机中字符串常量池类似为一个固定大小的HashTable,保存的是字符串(key)和 字符串对象的引用(value)的映射关系,字符串对象的引用指向堆中的字符串对象。

 注意:JDK1.7 字符串常量池和静态变量从永久代移动了 Java 堆中。

 JDK 1.7 为什么要将字符串常量池移动到堆中?

永久代(方法区实现)的 GC 回收效率太低,Java 程序中通常会有大量的被创建的字符串等待回收,将字符串常量池放到堆中,能够更高效及时地回收字符串内存,避免内存溢出。

7.直接内存

 直接内存并不是虚拟机运行时数据区的一部分,不会受到 Java 堆的限制,但会受到本机总内存大小以及处理器寻址空间的限制。

8.Java虚拟机对象创建过程
  1. 类加载检查,在运行时常量池中定位到这个类的符号引用,查这个符号引用代表的类是否已被加载过、解析和初始化过,决定是否执行类加载过程
  2. 为新生对象分配内存,分配方式有 “指针碰撞” 和 “空闲列表” 两种,虚拟机采用两种方式来保证内存分配并发线程安全:CAS+失败重试与TLAB
  3. 初始化零值,将分配到的内存空间都初始化为零值
  4. 设置对象头

  5. 执行 init 方法

9.对象的访问定位

Java 程序通过栈上的 reference 数据来操作堆上的具体对象,访问方式有以下两种:

  1. 句柄
  2. 直接指针

 

句柄 VS 直接指针 

句柄方式reference中存放的是对象实例数据与对象类型数据的地质,而直接指针方式reference中存放的是对象地址

使用句柄来访问 reference 中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而 reference 本身不需要修改。使用直接指针访问方式最大的好处就是速度快,它节省了一次指针定位的时间开销。 

10.补充

运行时常量池、方法区、字符串常量池是抽象概念,Metaspace、Heap 是与具体某种虚拟机实现相关的物理概念,是私有且具体的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值