1. Java内存区域划分
程序计数器
线程私有,程序计数器用来指示当前线程所执行的字节码的行号,是唯一一个没有指
OutOfMemoryError的区域。
虚拟机栈
线程私有,虚拟机栈描述Java方法执行的内存模型,每个方法在运行的时候都会创造一个栈帧,
用于存储局部变量表(存放编译期间已知的各种基本类型和对象引用类型和returnAddress类型,
其中long和double占用两个Slot)操作数栈、动态链接、方法出口等信息,每一个方法调用
到完成过程就是一个栈帧入栈到出栈的过程。
Thrown:StackOverFlowError 和 OutOfMemoryError
本地方法栈
线程私有,和虚拟机栈发挥的作用一样,只不过用来处理Native方法。
Thrown:StackOverFlowError 和 OutOfMemoryError
Java堆
线程共享,存放对象实例,垃圾收集器管理的主要区域。
Thrown:OutOfMemoryError
方法区
线程共享,存储被虚拟机加载的类信息、常量、静态变量、以及及时编译后的代码数据。
在HotSpot虚拟机实现的时候,永久代也用方法区实现,其他虚拟机则不存在永久带的概念。
运行时常量池的实现也在方法区。
Thrown:OutOfMemoryError
直接内存
Throw:OutOfMemoryError
2. 对象
对象的新建
对象内存布局
-----------------------------------------------------------------------------
对象自身的运行时数据(hashcode、 | 类型指针(指向它的类元数据的指针)
GC分代年龄、锁状态标识等) | 不是所有虚拟机都需要保留此指针
-----------------------------------------------------------------------------
对象的访问定位
- 使用句柄访问
在java堆内存中划分出一部分作为句柄池,refernce存放的就是对象的句柄地址。句柄中包含对象实例数据的地址和类型数据的地址。
- 使用直接指针访问
reference存放的就是对象的存储地址,此时对象就需要考虑如何存放如何访问对象类型数据的相关信息。