三、JMM
1、jvm运行时内存模型
1、线程所有:
PC:程序计数器
vm stack:虚拟机栈,栈帧为最小单位
native mechod(nm) stack:本地方法栈
2、共享:
heap:堆空间
mechod area:方法区,存放的是运行时常量池及class相关的对象。实现的话,1.8以前为perm space(永久区),1.8以后为meta space(元数据区)
3、特色:
direct mem:直接内存空间,主要nio操作的内存空间,不受jvm控制,需要通过native(unsafe类)区管理内存的创建释放等。
2、vmstack结构及关系
1、栈帧(参考)
一个栈帧代表了一个执行的方法。
- 局部变量表
- 在编译程序代码的时候就可以确定栈帧中需要多大的局部变量表,具体大小可在编译后的 Class 文件中看到。
- 局部变量表的容量以 Variable Slot(变量槽)为最小单位,每个变量槽都可以存储 32 位长度的内存空间。
- 在方法执行时,虚拟机使用局部变量表完成参数值到参数变量列表的传递过程的,如果执行的是实例方法,那局部变量表中第 0 位索引的 Slot 默认是用于传递方法所属对象实例的引用(在方法中可以通过关键字 this 来访问到这个隐含的参数)。
- 其余参数则按照参数表顺序排列,占用从 1 开始的局部变量 Slot。
- 基本类型数据以及引用和 returnAddress(返回地址)占用一个变量槽,long 和 double 需要两个。
- 操作数栈
- 同样也可以在编译期确定大小。
- Frame 被创建时,操作栈是空的。操作栈的每个项可以存放 JVM 的各种类型数据,其中 long 和 double 类型(64位数据)占用两个栈深。
- 方法执行的过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈和入栈操作(与 Java 栈中栈帧操作类似)。
- 操作栈调用其它有返回结果的方法时,会把结果 push 到栈上(通过操作数栈来进行参数传递)。
- 动态链接
- 每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态链接。
- 在类加载阶段中的解析阶段会将符号引用转为直接引用,这种转化也称为静态解析。另外的一部分将在运行时转化为直接引用,这部分称为动态链接。
- 返回地址
- 帧数据区
局部变量表用来存放方法的局部变量,包括传入的参数、内部定义的变量、返回值
进行具体操作的地方,出栈及入栈与局部变量表配合
方法开始执行后,只有 2 种方式可以退出 :方法返回指令,异常退出。
帧数据区的大小依赖于 JVM 的具体实现。
3、一个java class的大致存储示意