即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对象死亡,至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize
方法。当对象没有覆盖 finalize
方法,或 finalize
方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。
被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关联,否则就会被真的回收
四、内存分配策略
部分收集 (Partial GC):
-
新生代收集(Minor GC / Young GC):只对新生代进行垃圾收集;
-
老年代收集(Major GC / Old GC):只对老年代进行垃圾收集。需要注意的是 Major GC 在有的语境中也用于指代整堆收集;
-
混合收集(Mixed GC):对整个新生代和部分老年代进行垃圾收集。
整堆收集 (Full GC):收集整个 Java 堆和方法区
五、类加载的过程
它的整个生命周期可以简单概括为 7 个阶段::加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)。
六、类加载器
-
类加载器是一个负责加载类的对象,用于实现类加载过程中的加载这一步。
-
每个 Java 类都有一个引用指向加载它的
ClassLoader
。 -
数组类不是通过
ClassLoader
创建的(数组类没有对应的二进制字节流),是由 JVM 直接生成的。
【类加载器的主要作用就是加载 Java 类的字节码( .class
文件)到 JVM 中(在内存中生成一个代表该类的 Class
对象)
.双亲委派【重】
-
ClassLoader
类使用委托模型来搜索类和资源。 -
双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应有自己的父类加载器。
-
ClassLoader
实例会在试图亲自查找类或资源之前,将搜索类或资源的任务委托给其父类加载器。
简单总结一下双亲委派模型的执行流程:
-
在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载(每个父类加载器都会走一遍这个流程)。
-
类加载器在进行类加载的时候,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成(调用父加载器
loadClass()
方法来加载类)。这样的话,所有的请求最终都会传送到顶层的启动类加载器BootstrapClassLoader
中。 -
只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载(调用自己的
findClass()
方法来加载类)。 -
如果子类加载器也无法加载这个类,那么它会抛出一个
ClassNotFoundException
异常。