1、程序计数器
1、什么是程序计数器
当前线程所执行的字节码的行号指示器
2、特点
线程私有:每个线程都有一个独立的程序计数器,互不影响,独立存储,便于线程的切换
3、工作机制
所属的线程执行Java方法:记录虚拟机字节码指令地址
所属线程执行native方法:为空,
4、异常
不存在内存溢出等异常,例如outofMemoryErrory
2、Java虚拟机栈
1、什么是Java虚拟机栈
Java方法执行的内存模型
2、特点
线程私有:每个线程都有一个Java虚拟机栈,线程结束,栈帧也结束
3、工作机制
当Java方法被执行的时候会创建一个栈帧,存储了局部变量表、操作栈、动态连接、方法出口等消息。方法开始执行该栈帧入栈、方法结束该栈帧出栈。
4、补充
1、局部变量表:基本数据类型、对象引用类型、returnAddress类型
基本数据类型:Boolean(1)、byte(1)、char(1)、short(1)、int(1)、float(1)、long(2)、double(2)---占用的局部变量空间
对象引用类型:reference类型,指向对象起始地址的引用指针代表对象的句柄表示对象相关的位置
returnAddress:指向一条字节码指令的位置
2、局部变量表在编译期完成分配局部变量空间。运行期间不会再改变
3、两种异常:
stackOverflowError:线程请求的栈深度大于虚拟机所允许的深度
OutOfMemoryError:线程请求的深度超过了虚拟机动态扩展的深度
3、本地方法栈
1、什么是本地方法栈
Java native方法执行的内存模型
2、特点
同Java虚拟机栈
3、运行机制
同Java虚拟机栈(注意这里的本地方法栈仍然会抛出stackOverflowError、OutOfMemoryError两种异常。只是程序计数器不会抛出OutOfMemoryError异常)
总结:程序计数器、Java虚拟机栈、native虚拟机栈随线程而生,随线程而灭
4、Java堆
1、什么是Java堆
是Java虚拟机中存放对象实例的一块最大的内存区域。也是垃圾收集器管理的主要区域。
2、特点
- 所有线程共享
- 物理不连续、逻辑连续
3、运行机制
在Java虚拟机启动时创建,为所有的对象实例分配内存。当堆的内存无法完成实例分配的时候,会抛出OutofMemory异常。线程结束回收内存。
5、方法区
1、什么是方法区
存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码数据。
2、特点
- 所有线程共享
- 属于堆的一个逻辑部分
- 不需要连续的内存空间
- 同样也需要实现垃圾收集(虽然大家都把方法区当成了“永久代”)
3、运行机制
主要针对常量池的回收以及类型的卸载,无法满足内存分配需求时,抛出outofmemory异常
6、运行时常量池
1、什么是运行时常量池
存放编译期生成的各种字面量和符号引用。是方法区的一部分
2、特点
- 存储没有任何规范,不同的提供商可以自定义
- 动态性:运行期间还可以添加新的常量池
3、运行机制
类被加载时生成的字面量和符号引用存放在方法区的运行时常量池,超过内存的限制,抛出outofmemory异常
7、直接内存
1、什么是直接内存
native函数直接分配的堆外内存
2、特点
- 不属于虚拟机运行时数据区
- 不属于Java虚拟机的内存区域
- 不受Java堆大小的限制
- 受本机总内存的限制
3、运行机制
通过channel-buffer的I/O方式,利用Java堆的directbytebuffer作为直接内存的引用。当本机总内存大于本机物理内存,会抛出outofmemory异常