Java笔记之JVM内存区浅析

这篇博文是我看了《深入浅出虚拟机》《虚拟机规范》中的笔记
若有侵权,立即删除

JAVA虚拟机与java语言没有必然关系它只与特定的二进制文件格式class文件格式有所关联。

一个类加载进入虚拟机,虚拟机是如何完成对这个类信息的存储呢?
接来下我们就对虚拟机的内存区域进行浅显的分析

首先当虚拟机运行Java 程序时会将内存区划分为不同区域
这里写图片描述

1.PC寄存器 (Java虚拟机规范)

此区域是线程私有的(重要)
每一条Java虚拟机的线程都有自己的PC寄存器,
任意时刻一条线程只会执行一个方法代码
如果这个方法不是native(本地) 那么PC寄存器保存的就是正在执行字节码指令的地址。
如果是native方法 PC存储器的值是undefined。
此区域是唯一没有规定任何OutOfMemory的区域

2.Java虚拟栈

此区域是线程私有的(重要)
用图解释虚拟栈

public class Jvm {
    public static void main(String[] args) {
        Jvm jvm = new Jvm();
        jvm.a();
    }

    void a() {
        b();
    }

    void b() {}
}

首先运行这个Java程序时会创建一个线程来执行,创建此线程时虚拟栈跟着创建完成
虚拟机栈创建好了,开始执行main方法。将main方法加入到虚拟机栈中

这里写图片描述

然后在堆中创建jvm对象。
之后调用a()方法;
a方法加入栈
a方法中又调用b方法
将b方法加入栈

这里写图片描述

这是程序的调用过程
栈中的数据(a方法…)称为栈帧
栈帧随方法的调用而创建随着方法结束而销毁
每个栈帧都有自己的本地变量表(局部变量表),操作数栈,以及该方法所属类的运行常量池。
局部变量表和操作数栈在编译时期便可以确定。
局部变量表用来保存方法中的属性。

总之 就是执行方法时 先创建栈帧,栈帧中包含了此方法的数据等等。然后将此栈帧压入虚拟机栈,然后虚拟机依照先进后出的原则执行栈帧。直到栈为空程序结束。

3.本地方法栈

用来支持native方法的其余和虚拟机栈没啥区别。

4.Java堆

Java堆是线程共享的(重点)
Java堆是在虚拟机启动时就创建。是垃圾回收器的主要作用区域。
是所有类实例和数组对象分配内存的区域

5.方法区

方法区是线程共享的(重点)
虚拟机启动时创建。它存储了每一个类的结构信息。
如:运行常量池,字段,方法数据,构造函数,和普通方法的字节码内容。

6.运行常量池
由于运行常量池运行时创建的而且运行常量池是在方法区中分配内存的
所以这里没有将它加入到内存区中
存储了从编译时期可知的数值字面量到必须在运行解析后才能获取方法或字段的引用。在加载类和接口到虚拟机后就创建对应的运行常量池。

总结
这里写图片描述

水平有限 若有错误 欢迎指正重点内容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章