文章目录
1.2 多线程
JVM的后台线程:
- 虚拟机线程:?虚拟机线程在JVM到达安全点(SafePoint)时出现。
- 信号分发线程:?信号分发线程接收发送到JVM的信号并调用JVM方法。
- 编译器线程
- 垃圾回收器线程
- 定时任务线程
1.6 Java中的4种引用类型
- 强引用:通过赋值实现;无论内存足或不足都不回收。
- 软引用:通过SoftReference类实现;内存不足时回收。
- 弱引用:通过WeakReference类实现;无论内存足或不足都回收。
- 虚引用:通过PhantomReference类、ReferenceQueue类联合实现;无论内存足或不足都回收;对象回收前会被放进引用队列,所以虚引用可以用于追踪对象的回收状态。
1.1 JVM的运行机制
有多个进程启动就会实例化多个虚拟机实例。
Java程序的运行过程:
- 编译器编译:.java源文件 -> .class 字节码文件。
- JVM编译:.class字节码文件 -> 相应操作系统的机器码。
- 本地接口库:机器码调用本地接口库执行本地方法库中的本地方法。
JVM的组成:
- 类加载器子系统
- 运行时数据区:虚拟机栈、本地方法栈(区)、程序计数器、虚拟机堆、方法区
- 执行引擎:即时编译器、垃圾回收器件
- 本地接口库
1.10 JVM的类加载机制
1.10.1 JVM的类加载阶段
- 加载:读取Class文件到方法区,创建Class对象存放到虚拟机堆。方式:Class文件读取、jar包war包中的Class文件读取、动态代理自动生成的Class文件读取。
- 验证:验证Class符合JVM要求。
- 准备:final变量赋初始值。
- 解析:将常量池中的符号引用替换为直接引用。
- 初始化:静态变量赋初始值、执行静态代码块。先初始化父类,再初始化子类。
- 使用
- 卸载
1.10.2 类加载器
- 自定义类加载器:继承java.lang.ClassLoader类实现。
- 应用类加载器:加载用户路径(classpath)上的类库。
- 扩展类加载器:加载Java_HOME\jre\lib\ext目录中的类库,或通过java.ext.dirs系统变量指定路径中的类库。
- 启动类加载器:加载Java_HOME\jre\lib中的类库,或通过-Xbootclasspath参数指定路径中的类库。
1.10.3 双亲委派机制
双亲委派机制的核心是保障类的唯一性。
1.10.4 OSGI
OSGI(Open Service Gateway Initiative)是Java动态化模块化系统的一系列规范,旨在为实现Java程序的模块化编程提供基础条件。基于OSGI的程序可以实现模块级的热插拔功能,在程序升级更新时,可以只针对需要更新的程序进行停用和重新安装,极大提高了系统升级的安全性和便捷性。
OSGI提供了一种面向服务的架构,该架构为组件提供了动态发现其他组件的功能,这样无论是加入组件还是卸载组件,都能被系统的其他组件感知,以便各个组件之间能更好地协调工作。
OSGI不但定义了模块化开发的规范,还定义了实现这些规范所依赖的服务与架构,市场上也有成熟的框架对其进行实现和应用,但只有部分应用适合采用OSGI方式,因为它为了实现动态模块,不再遵循JVM类加载双亲委派机制和其他JVM规范,在安全性上有所牺牲。
1.3 JVM的内存区域
- 堆外内存:?在并发编程中被频繁使用。
- 虚拟机栈:线程私有;使用栈帧(存放局部变量、操作数栈、动态链接也就是符号引用、方法出口)的入栈、出栈来描述Java方法的执行过程,理解下图。
- 本地方法栈(区):线程私有;使用栈帧的入栈、出栈来描述本地方法的执行过程。
- 程序计数器:线程私有;唯一不会内存溢出;执行Java方法时存放字节码指令地址,执行本地方法时值为Undefined。
- 虚拟机堆:线程共享;参考1.4。
- 方法区(永久代):线程共享;存放机器码、常量池、常量、静态变量、类的元数据,注意Java8特性变化,参考1.4.3。
1.5 垃圾回收与算法
1.5.1 如何确定垃圾
1.5.2 Java中常用的垃圾回收算法
1.4 JVM的运行时内存
1.4.1 新生代
MinorGC、复制算法、短生命周期的对象、小对象
相关配置项:
- -XX:PretenureSizeThreshold # 配置晋升大对象的大小,默认为2KB~128KB
- -XX:MaxTenuringThreshold # 配置晋升老年代的年龄,默认为15
1.4.2 老年代
MajorGC、标记整理法、长生命周期的对象、大对象
1.4.3 永久代
Java8新变化:使用元空间取代方法区(永久代),元空间直接使用操作系统内存。常量池、机器码、常量、静态变量放到虚拟机堆,类的元数据放到元空间。
1.7 分代收集算法和分区收集算法
- 分代收集算法:JVM根据对象存活周期的不同将内存划分为新生代、老年代和永久代,并根据各年代的特点分别采用不同的GC算法。
- 分区收集算法:分区算法将整个堆空间划分为连续的大小不同的小区域,对每个小区域都单独进行内存使用和垃圾回收。
1.8 垃圾收集器
1.8.1 Serial垃圾收集器
复制算法;单线程;JVM在Client模式下新生代的默认垃圾收集器。
1.8.2 ParNew垃圾收集器
复制算法;多线程;JVM在Server模式下新生代的默认垃圾收集器。
相关配置项:
- XX:ParallelGCThreads # 配置ParNew垃圾收集器的工作线程数,默认与CPU线程数相等
1.8.3 Parallel Scavenge垃圾收集器
复制算法;多线程;自适应调节策略。
相关配置项:
- -XX:MaxGCPauseMillis # 配置最大垃圾收集停顿时间
- -XX:GCTimeRatio # 配置吞吐量大小
- -XX:+UseAdaptiveSizePolicy # 开启自适应调节策略
- -XX:-UseAdaptiveSizePolicy # 关闭自适应调节策略
1.8.4 Serial Old垃圾收集器
标记整理法;单线程;JVM在Client模式下老年代的默认垃圾收集器。
1.8.5 Parallel Old垃圾收集器
标记整理法;多线程。
1.8.6 CMS垃圾收集器
标记清除法;多线程。
垃圾回收过程:
- 初始标记
- 并发标记
- 重新标记
- 并发清除
1.8.7 G1垃圾收集器
标记整理法;多线程;内存区域独立划分使用;根据不同优先级回收各个区域。
1.9 Java网络编程模型
学习笔记:《Offer来了(原理篇)》第1章 JVM之Java网络编程模型