前面了解到 字节码文件通过类加载器加载到内存区域中的堆和方法区 使得jvm可以操作字节码指令
组成部分:
应用场景:
这一章总结的就是运行时的内存结构
运行时数据区第一部分----程序计数器
根据上上图程序计数器是线程不共享的 所以每个单一的线程都有自己的程序计数器
程序计数器的作用:
1. 存在内存中的字节码指令最终要给解释器执行,而解释器通过程序计数器保存的每一行字节码指令的地址就可以找到指令。所以程序计数器保存的永远是我们接下来要执行的字节码指令的地址
2.它可以用来控制解释器解释执行的顺序;在多线程情况下 线程来回切换时 用来保存接下来要执行的指令 方便线程继续执行
思考:
第二部分:栈
栈的作用
JAVA虚拟机栈用来保存用java实现的方法 每次执行方法会把方法的信息往栈里进行保存
而本地方法栈用来执行的是带有native本地关键字的用c++来编写的方法
但hotspot执行人员发现都反正是方法 于是将两个不同的方法信息都会保存在Java虚拟机栈中
如何保存方法信息:
栈帧的组成:
(1)局部变量表:
(2)操作数栈
(3)帧数据
动态链接
方法出口
异常表
java虚拟机内存溢出:
第三部分---堆
堆 方法区 直接内存 都是可以在线程中数据共享的区域
创建出来的对象都位于堆中 那么访问堆对象信息可以将对象内存地址保存到堆或静态变量中 当然在局部变量保存的内存地址在其他线程中无法使用 但如果是静态变量保存对象的引用 那么就可以不同线程中共享对象 所以说堆内存是线程之间可以共享的数据区域(JDK8及之后静态变量存放在堆中,8之前存放在方法区)
java虚拟机如何管理堆内存: