对象引用
判断对象是否需要回收,有“可达性分析算法”:通过一系列的GC Roots对象作为起点,从这些节点开始向下搜索,所走过的路径叫做引用链,,但一个对象到GCRoots没有任何引用链相连(图论:从GCRoots到这个对象不可达), 则证明此对象可回收。
可作为GC Roots的对象包括:
虚拟机栈中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
JNI Native方法引用的对象
-
强引用
Object obj = new Object()
有引用就永远不会回收
-
软引用
软引用回收发生在内存溢出之前,JVM再抛出内存溢出异常之前,会回收一次软引用对象,如果依旧内存不足才会抛出内存溢出异常
-
弱引用
弱引用对象只能存活到下一次GC之前
-
虚引用
虚引用只是用来接收对象被GC时的通知
垃圾回收算法
-
标记清除法
-
复制清除法
一块Eden,两块Survivor,每次将Eden和一块Survivor(A)复制到另一块Survivor(B),然后清理Eden和Survivor(A); 如果Survivor(B)可能不能存放Eden和Survivor(A)的数据,所以又分配担保机制,衍生出老年代的概念
-
标记整理法
-
分代回收算法
老年代使用‘标记清除’或者‘标记整理’
新生代使用复制算法
JVM类加载
-
加载
加载记加载字节码文件,即.class文件。通过全路径名加载字节码文件;将自己字节码的静态存储结构转化为内存方法区的数据结构;生成一个java.lang.Class对象
-
链接
-
验证
链接-验证。验证文件格式,以魔数0XCAFEBABE开头的文件,验证字节码文件能被正确的解析并存储与方法区内;元数据验证,验证字节码符合Java语法规范;字节码验证,验证方法逻辑;符号引用验证,验证字节码文件中的符号引用:类、方法、作用域(private、protected、public、friendly)
-
准备
链接-准备。对类的静态变量在方法区进行内存分配
-
解析
链接-解析。将字节码文件常量池中的符号引用替换为直接引用
-
-
初始化
初始化。对静态变量进行赋值,执行static方法
-
使用
-
卸载
加载和链接是不是同步进行的,加载过程中开始链接操作
同一个类字节码文件,被不同的ClassLoader加载,两个Class对象不一样
只存在两种类加载器:
- JVM中的Bootstrap ClassLoader,由C++实现,JVM的一部分
- 继承自java.lang.ClassLoader的java语言的类加载器
ClassLoader优先级
B o o t s t r a p C l a s s L o a d e r > E x t e n s i o n C l a s s L o a d e r > A p p l i c a t i o n C l a s s L o a d e r > U s e r C l a s s L o a d e r A U s e r C l a s s L o a d e r B Bootstrap ClassLoader > Extension ClassLoader > Application ClassLoader > \frac{User ClassLoader A}{User ClassLoader B} BootstrapClassLoader>ExtensionClassLoader>ApplicationClassLoader>UserClassLoaderBUserClassLoaderA
双亲委派模型
- 子ClassLoader在需要加载一个类时会先委托上级ClassLoader去加载这个类
- 只有当上级类加载器无法加载此类的时候,子ClassLoader加载此类