第二章、Java内存区域与内存溢出异常

Java与C++的区别?

Java有自动内存管理,C++没有。

运行时数据区

  1. 程序计数器
    作用:执行Java方法,存放正在执行的字节码指令地址;执行本地方法,则为Undefined。
    大小:很小,存放正在执行的字节码指令地址。
    异常:存储内容固定,没有任何异常。
    线程私有:是线程私有的。
注意:
程序计数器与线程的上下文切换有关,进行上下文切换时,工作内容保存在程序计数器中。所以程序计数器必须是线程私有的。
  1. Java虚拟机栈
    作用:代表Java方法执行的内存模型,方法执行入栈,方法结束出栈,代表一个线程执行的所有方法过程。
    大小:动态可扩展
    异常:StackOverflowError和OutOfMemoryError
    线程私有:是线程私有的
注意:
栈帧
作用:一个栈帧代表一个方法的执行,存放局部变量表,操作数栈和动态链接等。
大小:编译期确定。
异常:无。
线程私有:是线程私有的。
局部变量表存放各种局部变量,64位变量占用两个slot,其它一个;使用下标代表局部变量在代码中的位置,从0开始,一般0代表this。
操作数栈:存放各种操作数以及中间结果。
  1. Java堆
    作用:存放对象实例。
    大小: 动态扩展
    异常: OutOfMemoryError
    线程私有: 不是线程私有,是线程共享的
注意:
Java堆是垃圾回收的主要区域,因为存放各实例对象,回收价值大。
Java堆可以划分为新生代和老年代,新生代可以划分为Eden区和From Survivor和To Survivor。
控制参数: -Xmx 最大值;-Xms 最小值。
  1. 方法区
    作用:存放常量,静态变量,类信息以及即时编译后的代码,是堆的逻辑区域。
    大小:可扩展。
    异常:OutOfMemoryError
    线程私有:不是线程私有,是线程共享的。
注意:
字符串常量池已经从方法区中移出。
JDK1.8以前使用永久代来进行垃圾回收,1.8之后使用元方法区替代。
  1. 运行时常量池
    作用:存放各种字面量和符号引用。
    大小:动态扩展
    异常:OutOfMemoryError
    线程私有:不是线程私有,是线程共享的。

Java对象的创建

  1. 首先在常量池中,能否定位到符号引用,并检查是否加载解析初始化过,不通过则执行加载解析初始化。
  2. 检查通过,为对象分配内存。
如果内存规整,使用指针碰撞,将指针移动对象所需空间大小即可。
内存不规整,使用空闲列表法,维护所有空闲的空间,从中查找符合大小的空间。
并发安全可以使用本地线程分配缓冲,为每个线程分配独立的空间,在自己的空间中创建对象。
也可以使用CAS保证线程安全。
  1. 分配完成,初始化零值。
  2. 设置对象头。
  3. 执行方法。
Start
是否加载解析初始化
分配内存
加载解析初始化
内存初始化零值
设置对象头
执行init方法
End

对象内存布局

分为三部分,对象头,示例数据和对其填充。

对象头

对象头中第一部分存储自身运行时数据,称为Mark Word

状态25bit hashCode4bit 年龄分代1bit 是否偏向锁2bit 锁标记
无锁hashCodeage001
状态25bit hashCode 4bit 年龄分代 1bit 是否偏向锁2bit 锁标记
GC11
轻量级锁指向栈中锁记录的指针00
重量级锁指向重量锁的指针10
状态23bit hashCode2bit Espoh4bit 年龄分代1bit 是否偏向锁2bit 锁标记
偏向锁指向偏向的线程IdEspohage100

对象头第二部分存储类型指针,来确定是哪个类的实例。
如果是数组,还要有第三部分存放数组长度。

实例数据

存放各种类型的字段内容,父类的在前,子类在后,相同宽度的字段放在一起。

对象的访问定位

句柄池

优势是对象实例指针发生变化,栈中局部变量表到句柄池的引用不会变化,始终保持稳定。
缺点是需要两次指针定位。

直接指针

优势是只需要一次访问定位,速度快。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值