clear old record
This commit is contained in:
93
203-Java/203.1-Java面试/205.13-JVM/JAVA-面试-JVM.md
Normal file
93
203-Java/203.1-Java面试/205.13-JVM/JAVA-面试-JVM.md
Normal file
@@ -0,0 +1,93 @@
|
||||
## JVM 运行机制
|
||||
|
||||
1. Java 源文件被编译器编译为字节码文件
|
||||
2. JVM 将字节码文件编译为相应操作系统的机器码
|
||||
3. 机器码调用相应操作系统的本地方法库执行相应方法
|
||||
|
||||
## JVM 后台运行线程
|
||||
|
||||
- 虚拟机线程:虚拟机线程在 JVM 达到安全点时出现
|
||||
- 周期性任务线程:通过定时器调度线程来实现周期性操作的执行
|
||||
- GC 线程:GC 线程支持 JVM 中不同的垃圾回收活动
|
||||
- 编译器线程:运行时将字节码动态编译成本地平台机器码,是 JVM 跨平台的具体体现
|
||||
- 信号分发线程:接收发送到 JVM 的信号并调用 JVM 方法
|
||||
|
||||
## JVM 内存区域
|
||||
|
||||
**线程私有**
|
||||
|
||||
- [[程序计数器]]
|
||||
|
||||
用于存储当前运行线程所执行的字节码行号指示器,执行 Native 方法则为空(Undefined),唯一无内存溢出问题区域
|
||||
|
||||
- [[虚拟机栈]]
|
||||
|
||||
存储局部变量表,操作数栈,动态连接,方法出口等,描述Java方法的执行过程
|
||||
|
||||
- [[本地方法区]]
|
||||
|
||||
为Native方法服务
|
||||
|
||||
**线程共享**
|
||||
|
||||
- [[JVM 堆]]
|
||||
|
||||
运行时数据区,线程共享,[[新生代]]、[[老年代]]、[[永久代]]
|
||||
|
||||
- [[方法区]]
|
||||
|
||||
- 存储常量,静态变量,类信息,即时编译器编译后的机器码,运行时常量池
|
||||
|
||||
**[[直接内存]]**
|
||||
|
||||
也叫对外内存, 不是 JVM 运行时数据区的一部分,NIO 模块提供对应的操作,可通过堆外内存避免 Java 堆与 Native 堆来回复制数据的性能和资源消耗,高并发场景下广泛使用
|
||||
|
||||
[[垃圾回收算法]]
|
||||
|
||||
4 种引用类型
|
||||
|
||||
[[强引用]]
|
||||
|
||||
把一个对象赋值给一个引用变量,强引用对象一定为可达性状态,不会被垃圾回收
|
||||
|
||||
[[软引用]]
|
||||
|
||||
只有在系统内存不足时会被回收
|
||||
|
||||
[[弱引用]]
|
||||
|
||||
只要垃圾回收就一定会被回收
|
||||
|
||||
[[虚引用]]
|
||||
|
||||
和应用队列联合使用,主要用于跟踪对象的垃圾回收状态,仅仅是为了被回收时获得一个通知
|
||||
|
||||
[[垃圾收集器]]
|
||||
|
||||
新生代
|
||||
|
||||
- [[Serial收集器]],单线程复制算法
|
||||
- [[ParNew]],多线程复制算法
|
||||
- [[Parallel Scavenge]],多线程复制算法
|
||||
|
||||
老年代
|
||||
|
||||
- [[CMS]],多线程标记清除算法
|
||||
- [[Serial Old]], 单线程标记整理算法
|
||||
- [[Parallel Old]],多线程标记整理算法
|
||||
|
||||
[[Garbage First]],多线程标记整理算法
|
||||
|
||||
网络编程模型
|
||||
|
||||
阻塞 I/O
|
||||
|
||||
非阻塞 I/O
|
||||
|
||||
多路复用 I/O
|
||||
|
||||
信号驱动 I/O
|
||||
|
||||
异步 I/O
|
||||
|
||||
[[类加载机制]]
|
||||
BIN
203-Java/203.1-Java面试/205.13-JVM/Pasted image 20230511131621.png
Normal file
BIN
203-Java/203.1-Java面试/205.13-JVM/Pasted image 20230511131621.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 135 KiB |
BIN
203-Java/203.1-Java面试/205.13-JVM/Pasted image 20230511131639.png
Normal file
BIN
203-Java/203.1-Java面试/205.13-JVM/Pasted image 20230511131639.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 131 KiB |
0
203-Java/203.1-Java面试/205.13-JVM/gc.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/gc.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/jconsole.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/jconsole.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/jmap.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/jmap.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/jstack.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/jstack.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/内存模型.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/内存模型.md
Normal file
102
203-Java/203.1-Java面试/205.13-JVM/类加载机制.md
Normal file
102
203-Java/203.1-Java面试/205.13-JVM/类加载机制.md
Normal file
@@ -0,0 +1,102 @@
|
||||
## 类的生命周期
|
||||
**加载**
|
||||
**验证**
|
||||
**准备**
|
||||
解析
|
||||
**初始化**
|
||||
使用
|
||||
**卸载**
|
||||
需要立即对类进行初始化的六种情况
|
||||
1. 遇到new getstatic putstatic invokestatic这四条字节码指令是,如果类型没有进行过初始化,则需要先触发其初始化阶段
|
||||
1. 使用new关键字实例化对象时
|
||||
2. 读取或设置一个类型的静态字段(被final修饰,已在编译期把结果放入常量池的静态字段除外)的时候
|
||||
3. 调用一个类型的静态方法的时候
|
||||
2. 使用java.lang.reflect包的方法对类型进行反射调用的时候,如果类型没有进行初始化,则需要先出发其初始化
|
||||
3. 当初始化类的时候,如果发现其父类没有进行过初始化,则需要先触发其父类的初始化
|
||||
4. 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类
|
||||
5. 当使用JDK7新加入的动态语言支持时,如果一个java.lang.invok.MethodHandle实力的最后解析结果为REF_getStatic,REF_putStatic,REF_invokStatic,REF_newInvokSpecial四种类型的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化
|
||||
6. 当一个接口中定义了JDK8新加入的默认方法(default)时,如果有这个接口的实现类发生了初始化,那该接口要在其前被初始化
|
||||
## 类加载的过程
|
||||
### 1. 加载
|
||||
过程
|
||||
1. 通过一个类的全限定名来获取定义此类的二进制字节流
|
||||
2. 将这个字节流锁代表的静态存储结构转化为方法区的运行时数据结构
|
||||
3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据访问入口
|
||||
### 2. 验证
|
||||
确保Class文件中的信息符合虚拟机规范,保证不会危害虚拟机的安全,同时避免恶意代码的攻击
|
||||
1. **文件格式验证**
|
||||
1. 是否以魔数0xCAFEBABE开头
|
||||
2. 主次版本号是否在虚拟机接受范围内
|
||||
3. 常量池中常量是否有不被支持的常量类型
|
||||
4. 指向常量的各种索引值中是否有指向不存在的常量或不符合类型的常量
|
||||
5. CONSTANT_Utf8_info类型常量中是否有不符合UTF-8编码的数据
|
||||
6. Class文件中各个部分及文件本身是否有被删除或附加的其它信息...
|
||||
2. **元数据验证**
|
||||
对字节码描述的信息进行语义分析
|
||||
1. 是否有父类(除Object之外)
|
||||
2. 是否继承了不允许继承的类(final修饰)
|
||||
3. 如果不是抽象类,是否实现了父类或接口中要求实现的所有方法
|
||||
4. 字段,方法是否与父类矛盾(覆盖final,不符合规则的方法重载)
|
||||
3. **字节码验证**
|
||||
通过数据流和控制流分析,确定程序语义合法,符合逻辑,对类的方法体即Class中的Code属性进行校验分析
|
||||
1. 保证任意时刻操作数栈的数据类型和指令代码序列都能配合工作,不会出现在操作栈放置一个int类型,使用却按照long类型加载如本地变量表中
|
||||
2. 保证任何跳转指令都不会跳转到方法体外的字节码指令上
|
||||
3. 保证方法体中的类型转换总是有效的,可以把一个子类对象赋值给父类数据类型,但是不能把父类对象赋值给子类类型或毫无继承关系完全不相干的数据类型
|
||||
4. **符号引用验证**
|
||||
该类是否缺少或被禁止访问它以来的某些外部类,方法,字段等资源
|
||||
1. 符号引用中通过字符串描述的全限定名是否能找到对应的类
|
||||
2. 指定类中是否存在符合方法的字段描述符及简单名称所描述的方法和字段
|
||||
3. 符号引用中的类,字段,方法的可访问性(public。。。)是否可以被当前类访问
|
||||
### 3. 准备
|
||||
为类中定义的变量(static静态变量)分配内存并设置初始值
|
||||
### 4. 解析
|
||||
将常量池内的符号引用替换为直接引用的过程
|
||||
> 符号引用:
|
||||
> 符号引用一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义的定位到目标即可
|
||||
> 直接引用:
|
||||
> 直接引用是可直接指向目标的指针,相对偏移量或是是一个能简介定位到目标的句柄
|
||||
1. 类或接口的解析
|
||||
2. 字段解析
|
||||
3. 方法解析
|
||||
### 5. 初始化
|
||||
虚拟机开始执行类中编写的Java代码
|
||||
根据程序员通过程序编码指定的主观计划区初始化变量和其他资源
|
||||
初始化阶段就是执行类构造器`<client>()`方法的过程,`<client>()`是Javac编译器的自动生成物,是编译器自动收集类中的所有类变量的赋值动作和静态语句块(atatic{}块)中的语句合并产生的
|
||||
## 类加载器
|
||||
”通过一个类的全限定名来获取描述该类的二进制字节流“这个动作放到Java虚拟机外部实现,以便让应用程序自己决定如何获取需要的类,实现动作的代码为“类加载器”
|
||||
### 类与类加载器
|
||||
任意一个类,都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间
|
||||
### 双亲委派模型
|
||||
> 两种类加载器
|
||||
> 启动类加载器,C++实现,虚拟机一部分
|
||||
> 其他类加载器,Java语言实现,独立于虚拟机外部,继承自抽象类java.lang.ClassLoader
|
||||
|
||||
**三层类加载器**
|
||||
1. 启动类加载器
|
||||
负责加载<JAVA_HOME>\\lib目录或被-Xbootclasspath参数指定的路径中
|
||||
2. 扩展类加载器
|
||||
类sum.misc.Launcher$ExtClassLoader中以Java代码实现的,加载<JAVA_HOME>\\lib\\ext目录中或被java.ext.dirs系统变量指定的路径中的所有类库
|
||||
3. 应用程序类加载器
|
||||
由sum.misc.Launcher$AppClassLoader实现,负责加载用户类路径(ClassPath)上的所有类库可以直接在代码中使用这个类加载器
|
||||
|
||||
**双亲委派模型**
|
||||
![[Pasted image 20230511131639.png]]
|
||||
除了顶层的启动类加载器之外,其余的类加载器都有自己的父类加载器
|
||||
如果一个类加载器收到了类加载的请求,首先不会自己去尝试加载这个类,而是委派给付类加载器去加载
|
||||
### 破坏双亲委派模型
|
||||
JNDI服务
|
||||
OSGi热部署
|
||||
## Java模块化系统
|
||||
JDK9引入的Java模块化系统
|
||||
**模块的定义**
|
||||
- 依赖其他模块的列表
|
||||
- 列出的包列表,即其他模块可以使用的列表
|
||||
- 开放的包列表,即其他 模块可以反射访问模块的列表
|
||||
- 使用的服务列表
|
||||
- 提供服务的事项列表
|
||||
### 模块的兼容性
|
||||
|
||||
### 模块化下的类加载器
|
||||
扩展类加载器被平台类加载器取代
|
||||
平台类加载器和应用程序类加载器都不再派生自java.net.URLClassLoader
|
||||
![[Pasted image 20230511131621.png]]
|
||||
0
203-Java/203.1-Java面试/205.13-JVM/调优.md
Normal file
0
203-Java/203.1-Java面试/205.13-JVM/调优.md
Normal file
Reference in New Issue
Block a user