JVM知识点总结
2021-03-28 19:21:15 1 举报
包括对象的创建、类加载、对象的访问、对象的回收
作者其他创作
大纲/内容
堆内存(99%)
可作为GC Roots的对象
对象访问
是
CAS+失败重试
java虚拟机外部实现
回收算法
标记-清除(标记出所有需要回收的对象,产生碎片)
finalize()方法覆盖或者已被调用过?
标记-整理算法(所有存活对象往内存空间一端移动),解决空间碎片问题
自定义类加载器
为静态变量分配内存并设置类变量初始值的阶段
对象是否存活
强引用(永远不会被回收)
符号引用验证(确保解析行为能正常执行)
弱引用(一会被回收)
初始化零值(内存空间初始化为0,但不包括对象头)
类加载器加载(双亲委派模型)
CMS收集器(基于标记-清除算法实现)
两种方式
执行init方法(<init>方法没有执行前,所有字段都还为0,执行Init方法后,按照程序员的意愿进行初始化
将常量池内的符号引用替换为直接引用的过程
哪些内存需要回收
判断方法
缺点
方法区中类静态属性引用的对象
指针碰撞
根据new指令参数在运行时常量池定位对应类的符号引用,并检查该符号引用所指向的类是否被加载
可达性分析
对象创建完毕
执行类加载器<clinit>()方法,<clinit>()方法包括类变量赋值以及静态语句块中的语句
垃圾收集器
对象最多经历两次标记
存在大量空间碎片
扩展类加载器
运行期间不会产生内存空间碎片
类加载过程
空闲列表
分配内存
什么时候
否
不可达,第一次标记
句柄访问(存储的是对象的句柄地址,句柄中包含了对象实例数据与类型数据各自具体的地址信息)
可以指定最大停顿时间
虚拟机内部的引用,如基本数据类型对应的Class对象
TLAB(本地线程分配缓存)
缺点:内存占用和程序运行时的额外执行负载要比CMS高
方法区(永久代)
对处理器资源敏感
在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
直接指针访问(reference中存储的直接就是对象地址)
字节码验证(确定程序语义是合法的、符合逻辑的)
软引用(内存不足时,会回收),适合做缓存
G1垃圾收集器(不会产生空间碎片),G1跟踪各个region里面的垃圾收集的价值大小,维护一个优先级列表。
加载
内存回收
优点
适用于内存不规整(CMS)
ThreadLocal中的threadLocalmap对应的键为弱引用
分代收集(新生代、老年代)
虚引用(通知作用)
其他所有的类加载器,继承自ClassLoader)
初始化
内存分配并发问题
无法解决对象的循环引用问题
new
类加载
适用于内存规整的垃圾回收机制(G1)
通过类的全限定名来获取定义此类的二进制字节流
虚拟机栈中引用的对象
方法区中常量引用的对象
优点:并发低停顿
引用计数(在对象中添加一个引用计数器,有引用时,计数器值加1)
类加载分类
应用程序类加载器
通过一系列GC Roots作为起始节点集,根据引用关系向下搜索。如果这个对象到GC Roots间没有任何引用链相连,则证明此对象是不可再被使用的
保证对象实例字段在Java代码中可以不赋初值就直接使用
无法处理浮动垃圾
解析
元数据验证(对字节码描述的信息进行语义分析)
启动类加载器(C++实现)是虚拟机自身的一部分
准备
将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
System.gc被调用
验证
分配大对象,内存不足时
对象回收
文件格式验证(验证字节流是否符号Class文件规范)
设置对象头(对象属于哪个类的实例、对象的哈希码、对象的GC分代年龄等)
引用类型
不可达对象会被放入队列中,执行finalize()方法
0 条评论
下一页