深入理解Java虚拟机读书笔记--第二章 Java 内存区域与内存溢出异常

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

 

Java 虚拟机运行时数据区域

1.      程序计数器

当前线程所执行的字节码的行号指示器

线程私有

在虚拟机的概念模型中, 字节码解释器就是通过改变这个计数器的值来选择下一条需要执行的字节码指令,分支,循环,调转,异常处理,线程恢复等基础功能都需要依赖这个计数器完成

 

2.      Java 虚拟机栈

线程私有

描述Java 方法执行的内存模型: 每个方法执行时创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息

3.      本地方法栈

和Java 虚拟机栈类似, 为本地方法(NativaMethod )服务

线程私有

 

4.      Java 堆

线程共享,  内存区域中最大一块

作用:存放对象实例

垃圾收集器管理的主要区域

Java 堆可以处于物理上不连续的区域, 只要逻辑上连续即可

 

5.      方法区

线程共享

存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

Java 虚拟机规范中描述为堆的一个逻辑部分,

hotSpot虚拟机使用永久代来实现方法区, Java8 的HotSpot 中, 永久代被移除, 取而代之的是Metaspace (Native Memory)

 

 

对象的内存布局:

对象头: 运行时数据和类型指针

实例数据: 代码中定义的对象各Filed数据

对齐填充: 占位符,hotSpot虚拟机要求对象起始地址为8字节的整数倍,即对象大小必须为8字节整数倍。

 

对象创建过程

虚拟机遇到new指令时:

1.      类加载检查

如果没有,则执行类加载过程

 

2.      为新对象分配内存

两种方式: 指针碰撞(内存规整时), 空闲列表

内存空间(不包括对象头)都初始化为零值

 

3.      对象头设置

对象是哪个类的实例,哈希码,GC分代年龄等信息

如果是数组, 对象头还记录了数组长长度,  所以可以通过数组的length 属性得到数组长度

4.      初始化

按照程序员的意愿初始化

域赋值,初始化快,然后是构造器

 

 

 

对象的访问定位:

1.      句柄

Java栈中对象变量存储的是对象句柄, Java 堆中划分一块做句柄池,句柄中包括对象的实际地址

 

2.      直接指针

Reference 中存储的就是对象的地址

 

   HotSpot 虚拟机使用的是直接指针方式, 所以一般说可以把Java的对象变量理解成C++中指针。 HotSpot 虚拟机中引用是通过指针实现的

 

 

 

 

更多关于编程语言, 数据库,算法等精品内容, 请访问  我的个人博客  huqijun.org

个人原创内容, 转载请注明来源!

你可能感兴趣的:(java)