强引用 ( Strong Reference )
强引用是利用最普遍的引用。假如一个工具具有强引用,那垃圾接纳器毫不会接纳它。当内存空间不敷,Java虚拟机甘愿抛出OutOfMemoryError错误,使措施异常终止,也不会靠随意接纳具有强引用的工具来办理内存不敷的问题。 ps:强引用其实也就是我们平时A a = new A()这个意思。
强引用特性
Final Reference
① 当前类或父类中含有一个参数为空,返回值为void的名为finalize的要领。
② 而且该finalize要领必需非空
详见:JVM源码阐明之FinalReference完全解读 – 你假笨
软引用 ( Soft Reference )
是用来描写一些尚有用但并非必需的工具。对付软引用关联着的工具,在系统将要产生内存溢出异常之前,将会把这些工具列进接纳范畴之中举办第二次接纳。假如这次接纳还没有足够的内存,才会抛出内存溢出异常。
对付软引用关联着的工具,假如内存富裕,则垃圾接纳器不会接纳该工具,假如内存不足了,就会接纳这些工具的内存。在 JDK 1.2 之后,提供了 SoftReference 类来实现软引用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用行列(ReferenceQueue)连系利用,假如软引用所引用的工具被垃圾接纳器接纳,Java虚拟机就会把这个软引用插手到与之关联的引用行列中。
留意:Java 垃圾接纳器筹备对SoftReference所指向的工具举办接纳时,挪用工具的 finalize() 要领之前,SoftReference工具自身会被插手到这个 ReferenceQueue 工具中,此时可以通过 ReferenceQueue 的 poll() 要领取到它们。
/** * 软引用:对付软引用关联着的工具,在系统将要产生内存溢出异常之前,将会把这些工具列进接纳范畴之中举办第二次接纳( 因为是在第一次接纳后才会发明内存依旧不富裕,才有了这第二次接纳 )。假如这次接纳还没有足够的内存,才会抛出内存溢出异常。 * 对付软引用关联着的工具,假如内存富裕,则垃圾接纳器不会接纳该工具,假如内存不足了,就会接纳这些工具的内存。 * 通过debug发明,软引用在pending状态时,referent就已经是null了。 * * 启动参数:-Xmx5m * */ public class SoftReferenceDemo { private static ReferenceQueue<MyObject> queue = new ReferenceQueue<>(); public static void main(String[] args) throws InterruptedException { Thread.sleep(3000); MyObject object = new MyObject(); SoftReference<MyObject> softRef = new SoftReference(object, queue); new Thread(new CheckRefQueue()).start(); object = null; System.gc(); System.out.println("After GC : Soft Get = " + softRef.get()); System.out.println("分派大块内存"); /** * ====================== 节制台打印 ====================== * After GC : Soft Get = I am MyObject. * 分派大块内存 * MyObject's finalize called * Object for softReference is null * After new byte[] : Soft Get = null * ====================== 节制台打印 ====================== * * 总共触发了 3 次 full gc。第一次有System.gc();触发;第二次在在分派new byte[5*1024*740]时触发,然后发明内存不足,于是将softRef列入接纳返回,接着举办了第三次full gc。 */ // byte[] b = new byte[5*1024*740]; /** * ====================== 节制台打印 ====================== * After GC : Soft Get = I am MyObject. * 分派大块内存 * Exception in thread "main" java.lang.OutOfMemoryError: Java heap space * at com.bayern.multi_thread.part5.SoftReferenceDemo.main(SoftReferenceDemo.java:21) * MyObject's finalize called * Object for softReference is null * ====================== 节制台打印 ====================== * * 也是触发了 3 次 full gc。第一次有System.gc();触发;第二次在在分派new byte[5*1024*740]时触发,然后发明内存不足,于是将softRef列入接纳返回,接着举办了第三次full gc。当第三次 full gc 后发明内存依旧不足用于分派new byte[5*1024*740],则就抛出了OutOfMemoryError异常。 */ byte[] b = new byte[5*1024*790]; System.out.println("After new byte[] : Soft Get = " + softRef.get()); } public static class CheckRefQueue implements Runnable { Reference<MyObject> obj = null; @Override public void run() { try { obj = (Reference<MyObject>) queue.remove(); } catch (InterruptedException e) { e.printStackTrace(); } if (obj != null) { System.out.println("Object for softReference is " + obj.get()); } } } public static class MyObject { @Override protected void finalize() throws Throwable { System.out.println("MyObject's finalize called"); super.finalize(); } @Override public String toString() { return "I am MyObject."; } } }
弱引用 ( Weak Reference )