程序计数器是一块较小的内存空间,字节码解释器工作时,通过改变该计数器的值来选择下一条需要执行的字节码指令,如果正在执行的是JAVA方法,计数器记录的是正在执行的虚拟机字节码指令的地址,如果执行的是native方法,则计数器值为空。程序计数器是线程私有内存区域。
虚拟机栈也是线程私有的,每个方法被执行时,虚拟机会创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。
局部变量表
局部变量表中存放着各种基本类型、对象引用、returnAddress类型。
区别于 Java 虚拟机栈的是,Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。也会有 StackOverflowError 和 OutOfMemoryError 异常。在HotSopt虚拟机中将本地方法栈和Java栈合二为一。
Java虚拟机管理的最大的一块内存区域,几乎所有的JAVA对象的实例都存放在堆中,堆是垃圾收集器管理的区域。Java堆可以是物理上不连续的区域。堆是所有线程共享的内存区域。
方法区也是所有线程共享的内存区域,用于存放已经被虚拟机加载的类型信息,常量,静态变量,即时编译器编译后的代码缓存。
运行时常量池
运行时常量池保存着Class文件中常量池表的各种字面量与符号引用,和运行时间所产生的新变量。
使用NIO的时候,使用Native函数库直接分配的堆外内存。
当碰上字节码指令new时
1. 检查能否在常量池中找到这个类的符号引用,并检查该类是否被加载,解析,初始化过。
2. 如果没有,进入类加载阶段
3. 类加载检查通过后,为新生对象分配内存
4. 将分配到的空间不包括对象头都初始化为0
5. 对对象头进行必要的设置
6. 执行构造方法
对象的内存布局可以划分为三部分:对象头、实例数据和对齐填充。
对象的访问方式主要有通过句柄和直接指针访问两种。
原文:https://www.cnblogs.com/starcloud/p/15169995.html