JVM 虚拟机原理简述

用户头像
破晓_dawn
关注
发布于: 2020 年 08 月 05 日

JVM组成架构

Java之所以可以实现跨平台运行,是因为运行在JVM虚拟机上,JVM屏蔽了底层系统的不同,为Java字节码文件构造了一个统一的运行环境。

其组成结构如下:

类加载器将对应.class 文件装在到方法区

当进入一个方法时,创建方法栈针,放到Java栈中顶部,局部变量也在栈中。

如果方法中有New class, 放入到中。创建的对象都放入堆中。

程序计数寄存器,记录执行到哪一行指令。

指令是java自己的指令,需要执行引擎将java的指令变成依赖的系统对应的指令。

java不同环境下,执行引擎不同,是本地编译出来的。

.class字节码文件,在不同到平台上是一样的。执行引擎,把.class变成本地代码执行。

Java字节码

Java可以在不同平台上运行,因为不同平台都是在执行.class文件。

字节码执行流程:



字节码指令给执行引擎,如果编译过会直接执行。若没有编译过,看方法调用计数器,如果次数超过阈值,则编译字节码,编译成可执行指令,放入code cache;如果没有超过,给解释器,解释器将字节码解释成多行本地指令,交给本地方法执行。

这里注意,“执行编译后的机器码”来源于“code cache”。

字节码文件编译过程:



类似于Sql的编译过程。源文件词法分析得到token流。通过语法分析,变成语法树。对语法树进行语义分析,生成字节码。生成的字节码,为虚拟机可执行的指令。

类加载器

字节码通过类加载器加载到JVM的方法区。JVM使用双亲委托模型,即,低层次的当前类加载器,不能覆盖更高层次类加载器已经加载的类。

堆&栈

类似于操作系统的堆栈。JVM有唯一的堆。每个线程有独立的栈。对象在堆中分片,但是引用在栈中

方法区&程序计数器

方法区存放加载进来的类字节码。程序运行方法区中的指令时,每个线程有自己的程序计数器,记录自己执行到的指令。

线程工作内存 & volatile

Java内存模型规定所有的变量都是存在主存当中,每个线程都有自己的工作内存。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行。

volatile 修饰的变量,写一定会刷到主内存,读一定从主内存中读。

保证多CPU情况下,多线程对同一变量可见。不过要注意,volatile只是保证对所有线程可见,但是线程是不安全的。只保证可见性,不保证线程安全性。

垃圾回收

参考:https://xie.infoq.cn/article/c265f3fde4a8bec04485f6ca1



发布于: 2020 年 08 月 05 日 阅读数: 13
用户头像

破晓_dawn

关注

慢慢,稳稳 2017.12.06 加入

业余选手,但是有一颗向往专业的心

评论

发布
暂无评论
JVM虚拟机原理简述