Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域
这些区域有各自的用途,创建以及销毁的时间
有的区域随着虚拟机进程的启动一直存在
计数器的功能
当前线程所执行的字节码的行号指示器
计数器的工作
字节码解释器在工作时通过改变这个计数器的值,选取下一条需要执行的字节码指令
程序控制流的指示器
分支、循环、跳转、异常处理、线程恢复等基础功能都依赖于程序计数器
线程私有
在任何一个确定的时间,一个处理器(多核处理器的一个内核)都只会执行一条线程中的指令
每个线程拥有独自的程序计数器可以保证线程切换后可以恢复到正确的执行位置
计数器的值
线程正在执行Java方法时,计数器记录的是正在执行的虚拟机字节码指令的地址
线程正在执行本地(Native)方法时,计数器值为空(Undefined)
线程私有
生命周期线程相同
功能
描述Java方法执行的线程内存模型
每个方法被执行的时候都会同步创建一个栈帧
每个方法被调用直至执行完毕的过程,对应着一个栈帧从虚拟机栈中入栈到出栈的过程
局部变量表存储内容
编译期可知的各种基本数据类型
对象引用
可能是一个指向对象起始地址的引用指针
可能是指向一个代表对象的句柄或者其他与此对象相关的位置
returnAddress类型
指向一条字节码指令的地址
异常状况
StackOverflowError
线程请求的栈深度大于虚拟机所允许的栈深度
OutOfMemoryError
栈扩展时无法申请到足够的内存
服务于虚拟机使用到的本地方法
和Java虚拟机栈的功能类似
异常状况
StackOverflowError
线程请求的栈深度大于虚拟机所允许的栈深度
OutOfMemoryError
栈扩展时无法申请到足够的内存
线程共享
虚拟机启动时被创建
存放对象实例
Java堆可以处于物理上不连续的内存空间中
Java堆可以是固定的,也可以是可扩展的(-Xmx和-Xms参数实现)
异常状况
OutOfMemoryError
在Java堆中没有内存可以进行实例分配,堆也无法再扩展时
线程共享
存储内容
已被虚拟机加载的类型信息,如类名,字段描述,方法描述
常量
静态变量
即时编译器编译后的代码缓存
可以处于物理上不连续的内存空间中
可以是固定的,也可以是可扩展的,还可以选择不实现垃圾回收
OutOfMemoryError
方法区无法满足新的内存分配需求时
方法区的一部分
Class文件
类的版本
字段
方法
接口等描述信息
常量池表
存放编译期生成的各种字面量与符号引用
动态性
运行期间也可以将新的常量放入池中
如String类的intern()方法
把字符串对象加入常量池中
让有相同值的引用指向同一个位置
如果引用值变化了,但是常量池中没有新的值,那么就会新开辟一个常量结果来交给新的引用
当常量池中不存在这个字符串的引用时,将这个对象的引用加入常量池,返回这个对象的引用
当常量池中存在这个字符串的引用,返回这个对象的引用
OutOfMemoryError
常量池无法再申请到内存时
不是虚拟机运行区域的一部分
NIO类
一种基于通道与缓冲区的I/O方式
使用Native函数库直接分配堆外内存,通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作
避免了在Java堆和Native堆中来回复制数据
OutOfMemoryError
服务器管理员在配置虚拟机参数时,会根据实际内存区设置参数信息,忽略掉直接内存,造成各个内存区域总和大于物理内存限制,导致动态扩展时出现异常
原文:https://www.cnblogs.com/LittleSkinny/p/14419902.html