jvm
2023-08-23 10:59:14 0 举报
AI智能生成
JVM模型:工作原理、类加载子系统、执行引擎、垃圾回收、运行时数据区、即时编译器
作者其他创作
大纲/内容
JVM的调优
调整堆内存大小:通过-Xms和-Xmx参数调整堆内存的初始大小和最大大小,避免频繁的垃圾回收。
选择合适的垃圾回收器:根据应用场景选择合适的垃圾回收器,如CMS、G1等。
优化代码性能:通过合理的算法和数据结构选择、减少对象的创建和销毁等方式优化代码性能。
避免过度同步:减少锁的竞争,提高并发性能。
JVM的调试工具
jmap:生成堆转储快照,用于分析内存使用情况。
jstack:生成线程转储快照,用于分析线程状态和死锁情况。
jconsole:监视和管理JVM的工具,提供图形界面。
jvisualvm:多合一的JVM监视和分析工具,集成了jconsole和其他插件。
问题
StackOverflow
heapOverflow
内存泄漏(Memory Leak)
在k8s上部署的集群,内存占用率达到xxx(90%)就重启
子主题
内存溢出(Memory Overflow)
基础
JVM(Java Virtual Machine)是Java虚拟机的缩写,是Java程序运行的环境和平台。
JVM的工作原理
JVM通过类装载器将Java源代码编译后的字节码文件加载到内存中,然后由执行引擎逐行解释执行或即时编译执行。
JVM使用垃圾回收器自动管理内存,回收不再使用的对象,避免内存泄漏和溢出。
JVM提供了丰富的运行时数据区,包括方法区用于存放类信息、堆用于存放对象实例、栈用于存放方法调用和局部变量等。
JVM的优点
跨平台性:JVM使得Java程序可以在不同的操作系统上运行,只需安装对应的JVM即可。
自动内存管理:JVM的垃圾回收器可以自动回收内存,减少手动内存管理的工作量。
安全性:JVM提供了安全管理机制,可以对Java程序进行安全控制,防止恶意代码的执行。
高性能:JVM的即时编译器可以将热点代码编译成本地机器码,提高执行效率。
结构
类加载子系统
类的生命周期
加载
通过全限定类名加载Class对象
class信息、静态变量、常量加载到方法区
创建Class对象指向class信息内存地址
验证
class文件格式
元数据验证
字节码验证
符号引用验证
准备
成员变量赋初始值(0)
解析
符号地址转化为引用地址
初始化
成员变量赋值(也就是执行构造函数 )
执行static代码片段
使用
卸载
类装载器(Class Loader)
负责将字节码文件加载到内存中,并生成对应的类对象。
分类
启动类加载器
扩展类加载器
应用程序类加载器
自定义类加载器
区别
双亲委派机制
是什么
类加载器的一种工作机制。当要加载一个类的时候会向上(父类)询问(委托)是否已加载过这个类,如果父类加载器无法加载该类,那么类加载器才会尝试自己加载
好处
沙箱安全机制
保证核心.class不能被篡改
及时篡改也不会去加载,就算加载也不是同一个.class对象
及时篡改也不会去加载,就算加载也不是同一个.class对象
避免类重复加载
设想一个场景:用户在ClassPath中编写了一个java.lang.Object的同名类,如果没有双亲委派机制,每个类加载器都可以自行加载类,那么是不是会产生多个Object类呢?那程序使用的时候如何选择?唯一性就保证不了了
补充:全限定类名相同,并且类加载器是同一个,则会认为两个对象是同一个
补充:全限定类名相同,并且类加载器是同一个,则会认为两个对象是同一个
对象的创建(new创建)
类加载检查
是否已加载
分配内存
指针碰撞
空闲列表
初始化零值
设置对象头
执行init方法
执行引擎(Execution Engine):负责执行加载到内存中的字节码文件。
垃圾回收(Garbage Collection,GC)
是什么?
清理不再使用的对象,释放内存空间。
什么样的对象是垃圾?
JVM没有任何引用指向它的对象
为什么要回收?
如果不清理这些垃圾对象,那么它们会一直占用着内存,而不能给其他对象是用,最终垃圾对象越来越多,就会出现OOM
如何判断垃圾?
引用计数法
每个对象都保存一个引用计数器属性,用户记录对象被引用的次数
优点
实现简单,计数器为0则表示是垃圾对象
缺点
需要额外的空间来存储引用计数
需要额外的时间来维护引用计数
无法处理循环引用问题
可达性分析
已GC Roots为起始点,一层一层找到所引用的对象,被找到的对象就是存活对象,那么其他不可达的对象就是垃圾对象
GC Roots包括
线程中虚拟机栈中正在执行的方法中方法参数、局部变量所对应的对象引用
线程中本地方法栈中正在执行的方法中方法参数、局部变量所对应的对象引用
方法区中保存的类信息中静态属性所对应的对象引用
方法区中保存的类信息中常量属性所对应的对象引用
算法
标记-清除
标记已经使用过的内存区域—>回收
缺点:有碎片
优点:适合存活对象比较多的情况下
标记-整理
标记空闲区域,将存活对象移动到内存的一端。相当于标记-清除算法执行完一次后再进行一次内存整理
优点:没有碎片、不需要额外内存空间
缺点:
效率要低于标记-清除算法、复制算法
也需要修改栈帧中的引用地址
复制
空间一分为二,每次用一块,GC时移动对象
缺点:空间折半、移动对象
优点:不会有空间碎片,适合存活对象比较少情况
运行时数据区(Runtime Data Area)
私有
Java虚拟机栈
栈帧
局部变量表
操作数栈
方法返回地址
动态链接
特点
不需要垃圾回收
线程太多/调用层次太多,会StackOutflow溢出
本地方法栈
native方法
程序计数器(PC)
记录待执行的下一条指令的地址
共享
方法区(元空间)
静态变量
常量
编译后的代码
类信息
堆
存放对象
线程之间共享
年轻代:2
Eden
优先分配在Eden区
Survivor
Survivor每次只会使用其中一个区域,每次Young GC存活的对象会从一个Survivor复制到另一个Survivor
老年代:1
超大对象
长期存活
动态年龄判断
空间分配担保
垃圾分配算法
分代垃圾收集
问题
花太多时间执行垃圾回收并且只能回收很少的堆空间
堆内存中的空间不足以存放新创建的对象
即时编译器(Just-In-Time Compiler):将热点代码(HotSpot)编译成本地机器码,提高执行效率。
实际一个接口的调用会产生多少占用?多少请求阻塞……
JVM调优 新生代老年代调优怎么配置?
结合项目
AR词云业务:所有人(200人)点击词云页面变白,
原因:每次点击词云都会调用接口,把所有的词加载进行计算,
老师那儿进行词云的计算,学生那儿不算查老师那儿(redis缓存,设置10s过期时间),
原因:每次点击词云都会调用接口,把所有的词加载进行计算,
老师那儿进行词云的计算,学生那儿不算查老师那儿(redis缓存,设置10s过期时间),
0 条评论
下一页