JVM相关知识
2025-01-30 09:52:25 0 举报
AI智能生成
JVM的思维导图
作者其他创作
大纲/内容
实战问题和解决方案
内存泄漏和溢出
含义
特点
正常情况
正常情况下,处理业务时,堆内存会出现上下起伏
业务频繁时候创建对象会升高,在Minor gc后内存大小会减少,但是最后的大小都基本接近
整体内存大小的浮动会在一个范围
异常情况
堆内存在业务处理时,持续增长
即使有gc,也不能把大部分的对象回收
长期观察,曲线呈持续增长趋势
原因
不正确的equals和hashCode()实现
内部类引用外部类
ThrealLocal的使用
String的intern方法
通过静态字段保存对象
资源没有正常关闭
解决办法
TOP命令监控
VisualVM工具监控
Arthas Tunnel监控
Prometheus+grafana监控
一、初识JVM
JVM是什么?
Java Virtual Machine,Java虚拟机,解释运行Java字节码文件的程序,包含在Jre中
主流的JVM
HotSpot(Oracle JDK)
HostSpot(Open JDK)
GraalVM
Dragonwell JDK(龙井)
Eclipse OpenJ9(原 JBMJ9)
JVM的作用
解释运行字节码文件
对象和内存管理
创建类和方法
在堆和方法区分配内存
自动的垃圾回收机制,回收不再使用的对象
优化代码运行效率
JVM的组成
类加载器(由java虚拟机提供给应用程序获取字节码文件的技术)
运行时数据区
执行引擎
解释器
即时编译器JIT(Just In Time)
垃圾回收器
本地接口
由C++编写的Native方法
二、深入了解JVM
JAVA字节码文件组成
基础信息
主次版本号
常量池计数
访问标识(public interface abstract)
本类、父类索引
访问、接口、字段数量
常量池
字符串字面量,包括字符串的值、类接口全限定类名
字段
类包含的全部字段信息
方法
init构造方法、clinit初始化方法、main方法等的字节码
属性
字节码指令
iconst_0
istore_1
iload_1
iadd
innc 1 by 1
putstatic
ifne 9 (+6)
getstatic
类加载器
作用
获取本地、动态代理生成或者网络传输的字节码文件,存至内存
分类
底层源码C++编写
启动类加载器
java语言编写
扩展类加载器
应用程序类加载器
双亲委派机制
含义
除了启动类加载器,其他类加载器都会有一个父类加载器,保证类在加载时候,进行自下而上判断,然后自上而下进行加载
作用
保证基础类只能由启动类加载器加载,例如rt.jar里面的类,最常用的String、List等基本类,保证安全,同时也避免了类的重复加载问题
打破场景
Tomcat通过为多个web应用创建各自的类加载器,隔壁了应用,避免相同包相同类名的漏加载问题
类的生命周期
加载
类加载器根据类的全限定名获取字节码文件的二进制流,将字节码信息保存至方法区
在方法区上创建InstnceKClass对象,该对象包含类的基本信息(元信息),包含基本信息、常量池、字段、方法、虚方法表(实现多态使用到的)
在堆上创建java.lang.Class对象,只包含类的字段、方法信息,并与方法区的InstanceKClass对象关联
连接
验证
准备
解析
初始化
使用
回收
运行时数据区
线程共享
方法区
类的元数据
运行时常量池
字符串常量池
堆
JVM最大的内存块,通过-Xmx堆的最大大小,-Xms初始堆大小。new创建的对象都放堆中
线程私有
程序计数器
java虚拟机栈
局部变量表
操作数栈
帧数据
方法出口
动态链接
异常表
本地接口栈
垃圾回收算法
标记清除
含义
对GC ROOT引用链上的对象标记存活,然后清理未标记对象的内存
特点
清理的效率比标记整理的更快,但因为清理的对象的内存可能不连续,导致会出现内存碎片
复制清除
含义
将堆分为From和To区,创建对象会分配至From区,垃圾回收会将存活对象移动至To区,然后将名字互换
特点
对象移动过程,会进行整理,所以不会出现内存碎片,但只能在堆一半的内存区进行分配对象,对象能够使用的内存变小
标记整理
含义
对GC ROOT引用链上的对象标记存活,然后清理未标记对象的内存,并整理存活对象
特点
效率不如标记清除,但是不会产生内存碎片
分代回收
含义
将堆划分为年轻代和老年代,年轻代又分Eden和Survior区,Survior又分From和To区,
特点
对堆分年轻和老年区后,gc就可以针对某个区进行,这大大减少了gc的时间
区进行分代后,针对不同的区可以采用不同的回收算法
可以调整新生代的大小来适应一些应用场景
垃圾回收器
针对区
年轻代
Serial
ParNew
Paralle Scavenge
特点
对年轻代采用复制算法,gc采用多线程进行,期间会STW,关注的是吞吐量
优点
可以通过-XX:MaxGcPauseMillis=n设置最大暂停时间
可以通过-XX:GCTimeRadio=n设置吞吐量,例如n=19,那么用户线程执行时间=n/(n+1)=19/20=95%
垃圾回收器会根据1和2的设置值,自动调整堆大小
缺点
设置了吞吐量和最大暂停时间,会尽量保证去达到设置的吞吐量的值,而无法保证最大暂停时间
适用场景
适合无须与用户直接交互的系统,比如后台的任务执行
老年代
Serial Old
CMS(Concurrent Mark Sweep)
特点
关注系统最大暂停时间,采用标记清除算法对老年代进行gc回收,gc采用多线程
gc执行流程
初始标记
用极短的时间,标记GC ROOT直接引用的对象
并发标记
与用户线程并发执行,标记所有对象
重新标记
处理漏标(新建对象)、错标(引用改变)
并发清理
执行清除算法,用户线程不需要暂停
优点
可以设置最大暂停时间,尽量使系统卡顿的时间更短,提高用户体验感
缺点
采用清理算法回收,导致了内存碎片化
在并发清理与用户线程同时执行时,期间不会处理新建的对象,这就造成了“浮动垃圾”
老年代内存不足分配对象,CMS将退化成Serial Old
Paralle Old
年轻代和老年代
G1
特点
将堆划分成多个region区,可以作为Edion区、Survior区和Old区,通过-XX:G1HeapRegionSize设置region区的大小
可以通过-XX:MaxGCPauseMillis=n参数设置最大暂停时间
回收方式分2种,分别是:Young GC和Mixed GC
每次Young GC都会记录每个Eden区和Survior区的平均耗时,下次垃圾回收,可以根据最大暂停时间,来估算出本次能够回收的region区数量
gc执行流程
初始标记
标记GC ROOT直接引用的对象
并发标记
标记1种对象引用的对象,即GC ROOT间接引用的对象
最终标记
标记引用改变漏标的对象,不管新建对象、不再关联对象
并发清理
与用户线程可以并行执行,将对象移动至另外的region区,并清理原来区的对象
组合
串行gc
Serical+Serial Old
并行gc
ParNew+CMS
Paralle Scavenge + Paralle Old
G1
0 条评论
下一页