导图社区 JVM总结完整
JVM总结完整的思维导图,分享了内存模型、对象、垃圾回收、VM调优、Java常量池、逃逸分析的知识,一起来看。
社区模板帮助中心,点此进入>>
互联网9大思维
安全教育的重要性
组织架构-单商户商城webAPP 思维导图。
个人日常活动安排思维导图
域控上线
西游记主要人物性格分析
17种头脑风暴法
python思维导图
css
CSS
JVM
内存模型
类加载系统 class load
作用
负责加载类到内存
类加载器
启动类加载器 Bootstrap ClassLoader
java核心类加载器
扩展类加载器 Exe ClassLoader
java扩展类加载器
系统类加载器 System ClassLoader
负责加载系统类,加载classpath路径下的类
自定义类加载器 UserClassLoader
用户自定义类加载器
类加载顺序
加载
根据类路径去加载class文件并导入
验证
验证class文件的正确性
准备
为类中的静态变量分配内存(final修饰的静态变量在编译的时候已经分配内存)
解析
将常量池中的符号引用转变未直接引用
初始化
对静态变量、静态代码块完成初始化过程
双亲委派模式
定义
当类加载器收到类加载的请求时,它首先不会自己去加载这个类,而是把这个请求发送给父类进行加载,依次向上。只有父类无法加载这个类才会由子类去进行加载这个类,若子类也无法加载这个类,则会抛出ClassNotFound异常。
优点
不会重复加载某一个类
处于安全考虑,java核心类不会被随意替代
运行时数据区
线程共享区域
方法区
用于存储已被加载的类信息、常量、静态变量、即时编译后的代码等数据
当方法区无法满足内存分配时会抛出OOM异常
运行时常量池
方法区的一部分,用于存放编译期生成的各种字面量和符号引用
字符串常量池也属于运行时常量池的一部分。 1.7之后hotspot将字符串常量池移动到了堆区
1.8之前叫永久代,1.8之后叫元空间
Java堆区 Java Heap
占用内存最大,所有线程共享
主要存放对象实例,大部分对象在堆上分配内存
由于逃逸分析和即时编译技术的发展, 栈上分配内存(小对象未逃逸)
当堆中没有内存且无法扩展时会抛出OOM异常
老年代 2
长期存活的对象进入老年代(默认15次youngGC)
大对象进入老年代
年轻代 1
伊甸园 占比8
幸存区 占比1
直接内存
线程不共享区域
Java虚拟机栈
Java方法执行时的内存模型,java方法在被线程调用时,创建一个栈帧。
栈帧存储:局部变量、操作数栈、方法出口、动态链接等信息
局部变量表
局部变量存放的地方
操作数栈
操作树临时存放的区域
动态链接
符号引用转化为直接引用存放位置
方法存放在方法区,相当于把符号引用转化成内存地址
方法出口
方法执行完后返回主线程的位置
每一个方法从调用至执行完成的过程对应的栈帧在java虚拟机栈中入栈到出栈的过程。
本地方法栈
本地方法栈和虚拟机栈作用类似,不同的是本地方法栈是为native方法执行服务的
程序计数器
标识下一条需要执行的指定的位置
执行引擎
本地库接口
对象
User user =new User()
new User()创建一个对象,在堆上分配内存
User user 创建一个引用,内存分配在栈上
= 将User对象内存地址赋值给引用
Java对象模型
组成
对象头(Header)
MarkWord:存储对象运行时数据(hashcode、锁状态、GC年代)8/4字节(64/32位)
指针:类元数据指针,确定对象是哪个类的对象。8/4字节(指针压缩前后)
数组长度:只有数组对象有才有,占4字节
实际数据(Instance Data)
用于存储对象内各种类型的字段信息(含父类继承)
对齐填充(Padding)
java对象大小是8字节的倍数,如果不够8字节进行对齐填充
垃圾回收
垃圾回收机制
程序不需要显示的对释放对象占用内存,而是由JVM自行执行。
JVM有一个低优先级的垃圾回收线程,只在虚拟机空闲或堆内存不足时触发执行, 扫描所有未被引用的对象,加入垃圾回收的集合中进行垃圾回收处理。
GC垃圾收集(Gabage Collection)
GC判断策略
引用计数法
创建一个引用计数器,被对象引用+1,被释放一个引用-1, 为0时则可被回收。
优点:执行效率高,程序受影响比较小
缺点:不能解决循环引用问题
可达性分析算法
以GC Root对象为起点,搜索引用链。如果一个对象没有与 任何一条引用链相连时,则认为该对象是可回收对象
GC Root对象(两栈两方法)
虚拟机栈中引用的对象
本地方栈中引用的对象
方法区中类静态变量引用的对象
方法区中常量引用的对象
存活的线程
有系统加载器加载的类(可以通过静态属性的方式持有对象引用)
垃圾回收算法
标记-清除算法
第一阶段:从内存中标记被引用的对象
第二阶段:清理未被标记的对象
优点:实现相对简单,不需要移动对象
缺点:会造成内存碎片,该算法会暂定整个应用
复制算法
将内存分为大小相等的两块区域,当其中一块区域满了之后, 将存活的对象复制到另一块区域,同时将当前区域一次性清空。
缺点:内存使用率低,只有一半
标记整理算法
第一阶段:从根节点开始标记被引用的对象
第二阶段:将被引用对象复制到某一块区域中,将除此区域外的其他都区域清空
优点:集合了复制算法和标记清除算法的优点,不会造成大量内存碎片, 同时也避免了复制算法空间浪费的缺点
缺点:仍需解决对象复制的问题
分代算法
垃圾回收器
G1整堆、CMS老年代
GC
Young GC、Full GC(速度比YoungGC慢10倍)
空间分配担保
JVM调优
工具
jconsole 和 jvisualvm JDK自带的工具
MAT工具
JVM优化
GC优化
目的
减少FullGC的执行时间
减少转移到老年代的对象
选择合适的垃圾回收器
减少使用全局变量和大对象
设置合适的新生代、老年代大小
线程池
连接池
Java常量池
静态常量池
class文件中的常量池,包含字符串(数字)字面量、类、方法信息
jvm加载类操作完成后,将静态常量池载入到内存中,并保存到方法区
逃逸分析
方法逃逸
当一个对象在方法中定义之后,作为参数传递到其他方法中
线程逃逸
类变量或实例变量可能会被其他线程访问
当不存在逃逸现象后,可以通过 栈上分配、标量替换、同步消除的方式进行优化
同步消除
如果确定一个对象在线程中不会出现逃逸现象,则可以消除对象的同步锁
栈上分配
标量替换
标量是指不可分割的量
如果把一个对象分割,将其成员变量分割成基本类型来访问就叫做标量替换
如果发现一个对象不会逃逸,并且该对象可以被拆散,那么经过优化之后,不会直接生成该对象,而是生成若干个成员变量
JIT即时编译