jvm
点击勘误issues (opens new window),哪吒感谢大家的阅读

# jvm
(1) 基本概念:
JVM 是可运行 Java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、 一个垃圾回收,堆 和 一个存储方法域。JVM 是运行在操作系统之上的,它与硬件没有直接 的交互。
java代码的执行:代码编译为class,javac;装载class,ClassLoader;执行class,解释执行,编译执行,client compiler,server compiler。
# 双亲委派机制
双亲委派机制(Parent Delegation Model)是Java类加载器的核心机制,它定义了类加载器之间的层次关系和加载规则。
# 类加载器层次结构
启动类加载器(Bootstrap ClassLoader)
- 最顶层的类加载器,由C++实现
- 负责加载Java核心库(如rt.jar中的类)
- 加载路径:$JAVA_HOME/lib目录
扩展类加载器(Extension ClassLoader)
- 由Java实现,继承自ClassLoader
- 负责加载扩展库中的类
- 加载路径:$JAVA_HOME/lib/ext目录
应用程序类加载器(Application ClassLoader)
- 也称为系统类加载器(System ClassLoader)
- 负责加载应用程序classpath下的类
- 是用户自定义类加载器的默认父加载器
用户自定义类加载器(User Defined ClassLoader)
- 继承自ClassLoader类
- 可以实现特定的类加载逻辑
# 双亲委派工作流程
- 向上委派:当一个类加载器收到类加载请求时,首先将请求委派给父类加载器
- 逐级委派:父类加载器继续向上委派,直到达到启动类加载器
- 尝试加载:启动类加载器尝试加载该类,如果能够加载则返回Class对象
- 向下返回:如果父类加载器无法加载,则由子类加载器尝试加载
- 抛出异常:如果所有类加载器都无法加载,则抛出ClassNotFoundException
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
// 首先检查类是否已经被加载
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
// 委派给父类加载器
c = parent.loadClass(name, false);
} else {
// 委派给启动类加载器
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// 父类加载器无法加载时,由当前加载器尝试加载
}
if (c == null) {
// 调用findClass方法加载类
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
# 双亲委派的优势
- 安全性:防止核心API被篡改,确保Java核心库的类由启动类加载器加载
- 避免重复加载:确保同一个类在JVM中只有一个Class对象
- 层次清晰:类加载器之间形成清晰的层次关系
- 稳定性:保证Java程序的稳定运行
# 破坏双亲委派的场景
- 自定义类加载器:重写loadClass方法而不调用父类加载器
- 线程上下文类加载器:用于解决SPI(Service Provider Interface)加载问题
- OSGi框架:实现模块化的类加载机制
- 热部署:在不重启JVM的情况下更新类文件
内存管理:内存空间,方法区,堆,方法栈,本地方法栈,pc寄存器;内存分片,堆上分配,TLAB分配,栈上分配;
内存回收:算法 Copy Mark-Sweep, Mark-Compact;Sun JDK 分代回收 GC参数,G1
分代回收:新生代可用的GC 串行copying,并行回收copying,并行copying; Minor GC 触发机制以及日志格式; 旧生代可用的GC: 串行 Mark-Sweep-Compact ,并行 Compacting, 并发 Mark-Sweep Full GC 触发机制以及日志格式
内存状况分析:jconsole,visualvm,jstat,jmap,mat
线程资源同步和交互机制:
线程资源同步:线程资源执行机制;线程资源同步机制: Synchronized的实现机制,lock/unlock的实现机制
线程交互机制:Object.wait/notify/notifyAll, Thread.join, Thread.sleep, Thread.yield, Thread.interrupt; 并发包提供的交互机制: semaphore,CountdownLatch
线程状态以及分析方法:jstack、 tda
(2) 运行过程:
我们都知道Java源文件,通过编译器,能够生产相应的.Class文件,也就是字节码文件,而字节码文件又通过Java虚拟机中的解释器,编译成特定机器上的机器码。
也就是如下:
① Java 源文件—->编译器—->字节码文件
② 字节码文件—->JVM—->机器码
每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 Java 为什么能够 跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会 存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不 能共享。
运行时数据区 Runtime Data Area
方法区 Method Area (共享) 虚拟机栈 VM Stack (私有) 本地方法栈 Native Method Stack (私有) 程序计数器 Program Counter Register (私有)
堆 Heap (共享)
执行引擎:即时编译器 JIT 垃圾收集器 GC
本地库接口,本地方法库