四种引用方法,除了强引用外,其他3中引用均可以在java.lang.ref包中找到对应的类。 一、强引用 什么是强引用? 强引用指的是代码中普遍存在的Object obj=new Object()这类的引用,只要强引用存在,垃圾收集器就不会回收被引用的对象。 强引用特点: 1.强引用可以直接访问目标对象 2.强引用所指向的对象在任何时候都不会被系统回收,虚拟机宁愿抛出OOM异常,也不会回收强引用所指的对象。 3.强引用可能导致内存泄漏 强引用示例:StringBuffer str = new StringBuffer(“Hello world”); 例如: A a = new A(); B b = new B(a); a = null; 这样进行操作过后就会造成内存泄露 二、软引用 什么是软引用? 软引用是用来描述一些还有用,但非必须的对象。只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。 软引用特点: 1.软引用弱于强引用 2.软引用指向的对象会在内存不足时被垃圾回收清理掉 3.JVM会优先回收长时间闲置不用的软引用对象,对那些刚刚构建的或刚刚使用过的软引用对象会尽可能保留 4.软引用可以有效的解决OOM问题 5.软引用适合用作非必须大对象的缓存 软引用使用示例: String s = new String(“Frank”); // 创建强引用与String对象关联,现在该String对象为强可达状态 SoftReference softRef = new SoftReference(s); // 再创建一个软引用关联该对象 s = null; // 消除强引用,现在只剩下软引用与其关联,该String对象为软可达状态 s = softRef.get(); // 重新关联上强引用 这样可以消除强引用带来的内存泄露👆 三、弱引用 什么是弱引用? 弱引用与强引用相对,是指不能确保其引用的对象不会被垃圾回收器回收的引用。一个对象若只被弱引用所引用,则被认为是不可访问(或弱可访问)的,并因此可能在任何时刻被回收。 弱引用特点: 弱引用的使用和软引用类似,只是关键字变成了WeakReference。 弱引用的特点是不管内存是否足够,只要发生GC,都会被回收。 使用实例: WeakReference weakWidget = new WeakReference(widget); 使用weakWidget.get()就可以得到真实的Widget对象,因为弱引用不能阻挡垃圾回收器对其回收,你会发现(当没有任何强引用到widget对象时)使用get时突然返回null。 解决上述的widget序列数记录的问题,最简单的办法就是使用Java内置的WeakHashMap类。WeakHashMap和HashMap几乎一样,唯一的区别就是它的键(不是值!!!)使用WeakReference引用。当WeakHashMap的键标记为垃圾的时候,这个键对应的条目就会自动被移除。这就避免了上面不需要的Widget对象手动删除的问题。使用WeakHashMap可以很便捷地转为HashMap或者Map。 四、虚引用 什么是虚引用? 虚引用也称为“幽灵引用”或者“幻影引用”,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。 在JDK 1.2版之后提供了PhantomReference类来实现虚引用。 虚引用特点: 1.在回收直接内存的时候,靠的就是这个 2.模拟回收直接内存过程 3.创建一个低级的线程,一直监听虚引用关联的队列 4.一但队列有内容了,就根据队列存的入口地址。去执行相关的方法(释放直接内存) 使用示例: ReferenceQueue queue = new ReferenceQueue(); PhantomReference<byte[]> reference = new PhantomReference<byte[]>(new byte[1], queue); System.out.println(reference.get());
|