架构师每天都在思考什么?
- 如何让系统更快
- 如何避免系统出现瓶颈
垃圾收集机制为我们打理了很多繁琐的工作,大大提高了开发的效率,但是,垃圾收集也不是万能的,懂得JVM内部的内存结构、工作机制,是设计高扩展性应用和诊断运行时问题的基础,也是Java工程师进阶的必备能力。
#HotSpot 是官方的虚拟机(程序虚拟机)
java -version
JVM只关心字节码文件是否规范,可以由任意语言编写。
前端编译器(javac),后端编译器(解释运行,即时编译)
JVM特点
- Write once , Run Anywhere
- 自动内存管理
- 自动垃圾回收功能
JVM结构
- 字节码文件
- 类装载子系统
- 只负责加载class文件
- 流程
- Loading
- 过程
- 通过一个类的全限定名获取定义此类的二进制字节流
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
- 类的加载器
- BootClassLoader
- 非java语言编写
- 系统核心类库由此加载器加载
- PlatformClassLoader/ExtensionClassLoader
- AppClassLoader
- 自定义加载器
- 隔离加载类
- 修改类的加载方式
- 扩展加载源
- 防止源码泄露
- BootClassLoader
- 过程
- Linking
- 验证
- 确保Class文件的字节流中包含信息符合虚拟机要求,保证被加载类的正确性。
- 主要包括四种验证:文件格式验证,元数据验证,字节码验证,符号引用验证。
- 准备
- 为类变量分配内存并且设置默认值。
- finnal修饰的static在编译的时候就会分配
- 解析
- 将常量池内的符号引用转换为直接引用的过程
- 解析动作主要针对类或接口,字段,类方法,接口方法,方法类型等。
- 验证
- Initializing
- 初始化阶段就是执行类的构造器方法()的过程。
- 此方法由javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。
- 构造器方法中的指令按语句在源文件中出现的顺序执行。
- ()不同于构造器,构造器对应()
- 虚拟机保证一个类的()方法在多线程下被同步加锁。
- Loading
- 运行时数据区
- 方法区(共享内存)
- 堆(共享内存)
- Java 栈
- 本地方法栈
- 程序计数器
- 执行引擎(字节码指令 → 机器指令)
- 解释器
- JIT(编译执行)
- 垃圾回收器
- 本地方法接口
- 本地方法库
java源码 xxx.java → java编译器(词法分析,语法分析 → 语法树 →语义分析→注解抽象语法树→字节码生成器)→字节码文件 xxx.class → JVM
Java编译器输入的指令流基本上是一种基于栈的指令集架构,另外一种指令集架构则是基于寄存器的指令集架构。
栈
- 设计简单
- 指令集小(8位)
- 可移植性好
寄存器
- 性能优秀
- 指令集架构完全依赖硬件,可移植性差
- 指令少(16位)
JVM的生命周期
- jvm的启动
- 通过引导类加载器bootstrap class loader 创建一个 initial class,由jvm的具体实现来指定。
- jvm的执行
- 执行一个java程序,就是执行一个jvm的进程。
- jvm的退出
- 程序执行结束
- 遇到了异常或错误而终止
- 由于操作系统错误导致进程终止
- 线程调用Runtime类的exit方法
Hotspot的热点代码探测技术
- 通过计数器找到最具编译价值的代码,触发即时编译或栈上替换
- 通过编译器与解释器协同工作,在最优化的程序响应时间与最佳执行性能中平衡
常用的JVM
- Hotspot
- J9
- IBM Technology for Java Virtual Machine,简称IT4J,内部代号J9
- JRockit
https://docs.oracle.com/en/java/javase/17/
https://docs.oracle.com/javase/specs/jvms/se17/jvms17.pdf
https://docs.oracle.com/javase/8/docs/
https://docs.oracle.com/javase/specs/index.html
- 内存结构
- 类加载器与类的加载过程
- 类加载器的分类
- ClassLoader的使用说明
- 双亲委派机制
本地方法栈 与 本地方法接口 交互