把"GC Roots"的对象作为起点,然后向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,即该对象不可达,也就说明此对象是不可用的。
1、标记-清除算法:标记出所有需要回收的对象,标记完统一清除被标记的对象。
缺点:
2、复制算法:将内存分为大小相等的两块,每次只用一块,当这一块内存用完,将存活对象复制到另一块,将使用过的内存一次清理。
优缺点:
3、标记-整理算法:标记需要回收的对象,将存活对象向一端移动(整理),清理掉可回收的对象。
4、分代收集算法:根据对象存活周期不同,将Java堆内存分为新生代和老年代。
1、定义:
把Class文件加载到内存中,并对数据进行校验、解析和初始化,行成可被虚拟机直接使用的Java类型。类从被加载到虚拟机内存中开始,到卸载出内存结束。
2、生命周期:
3、需要对类进行初始化的场景
4、不会方法初始化的场景:
所有引用类的方式不会触发初始化,例如子类引用父类的静态字段,只触发父类初始化。
5、接口初始化和类初始化的区别:
接口初始化时,不要求其父类接口全部完成初始化。
包括加载、验证、准备、解析、初始化5步
1、加载:
2、验证:
3、准备: 为类变量(static修饰的变量)分配内存并设置变量初始值
4、解析: 将常量池符号引用替换为直接引用(直接指向目标的指针)的过程
5、初始化: 开始执行类中定义的Java代码
同一个Class文件,被两个不同的类加载器加载,这两个类不相等。相等包括equals、instanceOf、isInstance方法返回的结果。
1、类别:
2、双亲委托机制
除了顶层的类加载器外,其他的类加载器都有自己的父类加载器。父子之间通过组合来复用父加载器代码。
双亲委托机制的工作流程:一个类加载器收到类加载的请求,首先将请求委托给父类加载器去完成,最终所有加载请求都会传递给顶层的启动加载器中。当父加载器发现未找到所需的类而无法完成加载请求时,子加载器才尝试去加载。
ClassLoader
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { //检查请求的类是否已经被加载 Class<?> c = findLoadedClass(name); if (c == null) { try { if (parent != null) { //让父类加载器去尝试加载 c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { //父类加载器抛异常 } if (c == null) { //然后调用自身的findClass方法来进行类加载 c = findClass(name); } } return c; } 复制代码