美文网首页
知识回顾|引用、类加载

知识回顾|引用、类加载

作者: 三更冷 | 来源:发表于2023-02-04 21:11 被阅读0次

    本文回答以下问题,文内可能有遗漏、错误或表达不够清晰的地方。

    • 引用

    ① Java中的软引用、弱引用、虚引用的适用场景以及释放机制
    ② 软引用什么时候会被释放、弱引用什么时候会被释放

    • 类加载

    ① 双亲委派机制的作用
    ② 如何自己实现一个classloader打破双亲委派

    引用

    ① Java 中的软引用、弱引用、虚引用的适用场景以及释放机制
    ② 软引用什么时候会被释放、弱引用什么时候会被释放

    Java 的四种引用类型:
    ● 强引用:我们 new 出来的对象就是强引用类型,只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足的时候
    ● 软引用:使用 SoftReference 修饰的对象被称为软引用,软引用指向的对象在内存要溢出的时候被回收(OOM之前回收)
    ● 弱引用:使用 WeakReference 修饰的对象被称为弱引用,若对象仅被弱引用指向,在任何发生GC的时候其均可被回收
    ● 虚引用:虚引用是最弱的引用,在 Java 中使用 PhantomReference 进行定义。无法通过虚引用获取与之关联的对象实例,当对象仅被虚引用引用时,在任何时候其均可被回收。通常 PhantomReference 与引用队列 ReferenceQueue 结合使用,可以实现虚引用关联对象被垃圾回收时能够进行系统通知、资源清理等功能。

    软引用、弱引用、虚引用的实现都继承了 Reference 这个类,一个 Reference 对象创建后的生命周期如下:
    1、Native层,在GC时将需要被回收的 Reference 对象移动到 pending 链表;
    2、Java层,源源不断的从 pending 链表中提取出元素,将 非 Cleaner 类型(继承自虚引用)的对象加入到引用队列中,对于Cleaner 类型的对象会调用其 clean 方法,该方法主要是用来做对应的资源回收。在堆外内存 DirectByteBuffer 中就是用 Cleaner 进行堆外内存的回收,这也是虚引用在 java 中的典型应用

    软引用和弱引用应用场景:用于内存中不重要的数据缓存

    类加载

    ① 双亲委派机制的作用

    Java 里有如下几种类加载器:
    ● 引导类加载器(Bootstrap):负责加载支撑 JVM 运行的位于 JRE 的 lib 目录下的核心类库,比如 rt.jar、charsets.jar 等
    ● 扩展类加载器(Ext):负责加载支撑 JVM 运行的位于 JRE 的 lib 目录下的 ext 扩展目录中的 JAR 类包
    ● 应用程序类加载器(App):负责加载 ClassPath 系统类路径下的类包,主要就是加载开发者自己写的那些类
    ● 自定义加载器:负责加载用户自定义路径下的类包

    类加载器之间的关系:
    ● 启动类加载器(Bootstrap),由C++实现,没有父类
    ● 拓展类加载器(Ext),由Java语言实现,父类加载器为null

    ● 应用程序类加载器(App),由Java语言实现,父类加载器为拓展类加载器
    ● 自定义类加载器,父类加载器为应用程序类加载器

    双亲委派机制:加载某个类时会先委托父加载器寻找目标类,找不到再委托上层父加载器加载,如果所有父加载器在自己的加载类路径下都找不到目标类,则在自己的类加载路径中查找并载入目标类。

    比如我们自己写的类A:
    最先会找应用程序类加载器加载,应用程序类加载器会先委托扩展类加载器加载,扩展类加载器再委托引导类加载器
    顶层引导类加载器在自己的类加载路径里找了半天没找到A类,则向下退回加载A类的请求,
    扩展类加载器收到回复就自己加载,在自己的类加载路径里找了半天也没找到A类,又向下退回A类的加载请求给应用程序类加载器,
    应用程序类加载器于是在自己的类加载路径里找A类,结果找到了就自己加载了。

    为什么要设计双亲委派机制?
    ● 沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样便可以防止核心 API库 被随意篡改
    ● 避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次,保证被加载类的唯一性

    ② 如何自己实现一个 classloader 打破双亲委派

    • 重写类加载方法(loadClass)

    Tomcat 容器打破了双亲委派机制,实现了web应用的隔离:Tomcat 给每个 Web 应用创建一个类加载器实例(WebAppClassLoader),该加载器重写了 loadClass 方法,优先加载当前应用目录下的类,如果当前找不到了,才一层一层往上找(不会一开始就向上传递)

    参考文章

    Java魔法类:Unsafe应用解析
    Java引用类型原理剖析

    相关文章

      网友评论

          本文标题:知识回顾|引用、类加载

          本文链接:https://www.haomeiwen.com/subject/rexuhdtx.html