深入JVM内核(一)JVM内存区域与运行机制

date: 2018-10-03 13:01:52

JVM启动流程

JVM启动流程

JVM基本结构

JVM基本结构

程序计数器

  • 每个线程拥有一个PC寄存器
  • 在线程创建时创建
  • 指向下一条指令的地址
  • 执行本地方法师,PC的值为undefined

方法区

  • 所有线程共享
  • 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

Java堆

  • 所有线程共享
  • 和程序开发密切相关
  • 几乎所有的对象实例都在这里分配内存
  • 对分代GC来说,堆也是分代的
  • GC的主要工作区间

Java虚拟机栈

  • 线程私有
  • 生命周期与线程相同
  • 栈由一系列帧组成(因此Java栈也叫做栈帧)
  • 帧用于存储局部变量、操作数栈、动态链接、方法出口等信息
  • 方法从调用到执行完成的过程,就对应一个栈帧在虚拟机栈中入栈到出栈的过程
  • 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常

本地方法栈

  • Java虚拟机栈发挥的作用相似
  • 区别在于:
    • 虚拟机栈为虚拟机执行Java方法(也就是字节码)服务
    • 本地方法栈为虚拟机使用到的Native方法服务

堆、栈、方法区的交互

public class AppMain { 
 //运行时, jvm 把appmain的信息都放入方法区 
    public static void main(String[] args) {
    //main 方法本身放入方法区。
    Sample test1 = new Sample( " 测试1 " );
    //test1是引用,所以放到栈区里, Sample是自定义对象应该放到堆里面
    Sample test2 = new Sample( " 测试2 " );
    test1.printName();
    test2.printName();
}

public class Sample {
    //运行时, jvm 把appmain的信息都放入方法区
    private name;
    //new Sample实例后, name 引用放入栈区里, name 对象放入堆里
    public Sample(String name) {
        this .name = name;
    }
    //print方法本身放入 方法区里。
    public void printName() {
        System.out.println(name);
    }
}

JVM内存模型

内存模型

  • 每一个线程有一个工作内存和主存独立
  • 工作内存存放主存中变量的值的拷贝

  • 当数据从主内存复制到工作存储时,必须出现两个动作:第一,由主内存执行的读(read)操作;第二,由工作内存执行的相应的load操作;当数据从工作内存拷贝到主内存时,也出现两个操作:第一个,由工作内存执行的存储(store)操作;第二,由主内存执行的相应的写(write)操作.
  • 每一个操作都是原子的,即执行期间不会被中断
  • 对于普通变量,一个线程中更新的值,不能马上反应在其他线程中
    如果需要在其他线程中立即可见,需要使用 volatile 关键字

内存模型


参考:

  • 周志明. 深入理解JVM虚拟机
posted @ 2020-01-10 13:01  吹不散的流云  阅读(103)  评论(0编辑  收藏  举报