从零开始学习JVM

对于大部分学习Java语言的人来说,JVM是一个无法避免的必要知识点,接下来我将分享一下我的jvm学习笔记,希望能够给予各位一点帮助。

什么是jvm

Java virtual machine(java虚拟机),它是一种规范,虚构的一个计算机(有自己的字节码指令集和内存管理),也可称之为跨语言的平台,无论何种语言,只要编译为class文件,那么jvm就可以识别运行。
自己的理解:jvm可理解为一个黑盒子,它有两个口,一个用以接收class文件,内部经过一系列处理,从另一个口将命令传出去调用操作系统具体的指令,来完成自己的功能。可以说是类加载器、解释器、JIT编译器、执行引擎的集合,jvm只是给这个集合起的一个名字,只是方便人们用来交流而已。
在java中的地位可参考下图:
从零开始学习JVM_第1张图片

class文件

可以这么理解,class文件只是多种文件类型中的一种,有自己的独特格式,和txt文件、html文件类似,只是格式不同而已;这是jvm能够识别、解析的一种文件格式。
class文件内容:魔数(标识这是一个class文件)、 版本号、常量池大小、具体常量池…、当前类、接口、字段、属性、指令等信息。

类加载的过程

类加载包含3步,第一,loading(从磁盘读入内存);第二,linking(verification(验证文件是否符合jvm规范、preparation(静态成员变量赋默认值)、resolution(将类、方法、属性等符号引用解析为直接引用));第三,initializing(静态变量 初始化)。
jvm是按需动态加载类的,采用双亲委派机制(保证安全性)

过程描述:当需要加载一个类时,先获取自己的类加载器,询问是否该类已经加载,如是,则已加载直接使用,如否,则依次向自己的上级加载器询问,直到最上级Bootstrap,如果还没有加载,则判断该类是否在自己加载的范围,是,则加载,否,依次向下判断。类加载器之间并不是语法上的父子关系只是人为定义的上下级而已。

注:类加载 loading、linking、initializing
对象创建 申请内存、赋默认值、初始化

自定义类加载器

1.继承ClassLoad
2.重写findClass() 或者 loadClass()

注:像Tomcat等一般都有自己的类加载器,以此来实现热部署(丢弃以前的类,重新加载新类 需要重写loadClass方法)这种方法可以破坏双亲委派机制;重写findClass来实现自定义类加载器,这种写法不会破坏双亲委派机制。

jvm中代码的执行模式

编译与解释混合进行。一般情况下,jvm会使用字节码解释器对代码解释执行;对于热点代码,jvm会使用JIT编译器将代码编译为本地机器语言来执行。

Java Runtime Data Area(运行时数据区)

1.PC program counter 程序计数器,线程私有,存放指令的位置

2.虚拟机栈 线程私有,每个线程一个栈,栈里存放一个个的栈帧 每个方法一个栈帧,每个栈帧包含:

   	- 本地变量表 Local Variable Table  存放方法里的参数、局部变量
   	- 操作数栈 Operated Stack  对本地变量表里的数据操作的栈
   	- 动态链接 Dynamic Linking   保存着字符引用所代表的内存地址
   	- 返回地址 return address   方法结束后返回值应去哪

native stack 本地方法栈,类似于虚拟机栈,只是用来存放本地方法
3.方法区 (Method Area)线程共享,也称为永久代,堆外的一块空间
存放class的元数据信息,静态变量等信息

- perm space   1.8之前的方法区  字符串常量位于PermSpace FGC不会清理 大小启动的时候指定,不能变
- meta space  1.8之后的方法区 字符串常量位于堆 会触发FGC清理 不设定的话,最大就是物理内存

4.堆(heap) 线程共享
存放对象信息,创建的对象会保存在堆中

5.Direct Memory(直接内存)
jvm可以直接访问的内核空间的内存,也可称为有操作系统管理的内存
用途
NIO,以此实现zero copy ,来提升效率。
注:一般来说对于IO数据会放在内核空间,当jvm需要该数据时会从内核空间拷贝到jvm的内存空间

常见的指令

1.load    读操作
2.store   写操作
3.pop   弹栈
4.add  加
5.sub  减
6.mul   乘
7.div  除
8.invokeStatic   调用静态方法
9.invokeInterface   接口引用调用子类方法
10.invokeSpecial     调用构造方法 或  private修饰的方法
11.invokeDynamic   在使用lambda表达式等动态生成类时使用

你可能感兴趣的:(JVM)