相信之前看过我博客的小伙伴们,对下面这幅图一定很熟悉:
JVM即Java虚拟机,它是JRE的一部分,同时它也是一个虚拟的计算机。JVM拥有自己完善的硬件结构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言其中有一个特性就是跨平台性,主要就是通过JVM来实现的。
上面提到了跨平台性,所谓跨平台性主要指的是字节码.class文件可以在任何具有
JVM的计算机或者电子设备上运行,JVM中的解释器负责将.class字节码文件解释为
特定的机器码进行运行。
言归正传,接下来就正式进入主题
内存模型
类装载器
Java源代码编译成Java Class文件后通过类加载器ClassLoader加载到JVM中 。
每一个Java虚拟机都有一个类装载器,负责加载程序中的类和接口,并赋予唯一名字。
JVM中的类装载器主要分为两种:
- 启动类装载器:JVM实现的一部分
- 用户自定义类装载器:是Java程序的一部分,必须是ClassLoader的子类
执行引擎
负责加载类中所包含的指令。要么在执行本地方法,要么在执行字节码
动态内存管理器
堆(jdk1.8以后,运行时常量池也属于堆)
被所有线程共享的一块内存区域,在虚拟机启动的时候创建,用于存放对象实例
方法区
被所有方法线程共享的一块内存区域
用于存储已经被虚拟机加载的类信息,常量,静态变量等
程序计数器
程序计数器是线程私有的,每个线程单独持有一个程序计数器
它指向当前正在执行的字节码的行号。如果当前线程是native方法,则其值为null
栈(本地方法栈、JVM虚拟机栈)
- JVM虚拟机栈
JVM虚拟机栈是线程私有的
每个方法执行的时候会创建一个栈帧,存储了局部变量、操作数、动态链接地址等;
每个方法从调用到执行完毕,对应一个栈帧在虚拟机栈中的入栈和出栈
通常所说的栈,一般是指在虚拟机栈中的局部变量部分
局部变量所需内存在编译期间完成分配,
如果线程请求的栈深度大于虚拟机所允许的深度,则StackOverflowError
如果虚拟机栈可以动态扩展,扩展到无法申请足够的内存,则OutOfMemoryError
- 本地方法栈
和JVM虚拟机栈类似,但本地方法栈主要是为了native方法提供服务的