Java 虚拟机接管了全部的内存分配与回收工做,极大地减小了程序员的工做量和错误率。GC 在回收内存时,一般采用被称为可达性分析的算法判断一个对象是否能够回收。而在可达性分析中,对象的引用有着决定性的做用。在下图中,GC 从 GC Roots 开始顺着引用链往下寻找对象,发现当前有引用的对象为object 一、object 二、object 三、object 4,而object 五、object 六、object 7虽然互相之间有引用但已经没法从外部引用到。所以,图中 object 1-4 为存活的对象,而 object 5-7 为可回收的对象。程序员
虽然 GC 可以完成垃圾收集工做,可是仍然没法避免 out of memory 。一方面在开发过程当中须要注意再也不使用的引用设为 null 来释放引用的对象,另外一方面也须要从对象引用的角度考虑使用合适的引用类型更好地管理对象内存。算法
Java 有4种类型的引用:strong(强引用),soft(软引用),weak(弱引用)和 phantom(虚引用)。缓存
强引用:强引用是在 Java 中的普通引用。任什么时候候咱们建立一个新的对象,默认状况下建立一个强引用。例如类的静态变量,从类被初始化以后便已经分配内存,做为强引用对象不能被 GC 回收,须要等待虚拟机退出或类被卸载才能释放引用被 GC 回收。post
弱引用:弱引用没法保证对象必定存活于内存中,被弱引用关联的对象只能生存到下一次垃圾收集发生以前。咱们可使用 WeakReference 类来实现弱引用。性能
软引用:软引用比弱引用稍强一点,垃圾收集发生时弱引用必定会被回收,而软引用会请求 GC 保留本身除非没有其余选择,能够理解为只在将要发生内存溢出时 GC 才会回收软引用。咱们可使用 SoftReference 类来实现软引用。对象
虚引用:一个对象是否有虚引用的存在,彻底不会对其生存时间构成影响,也没法经过虚引用来取得一个对象实例。为一个对象设置虚引用关联的惟一目的就是能在这个对象被 GC 回收时收到一个系统通知。咱们可使用 PhantomReference 类来实现虚引用。当 GC 准备回收一个对象时,若是发现它还有虚引用,就会在回收对象的内存以前,把这个虚引用加入到与之关联的引用队列中。开发者能够经过判断引用队列中是否包含对象来判断对象是否即将被回收,能够在回收以前作些处理。队列
引用队列:若是引用关联了引用队列,则 GC 回收对象内存的时候会把引用加入到引用队列中。当引用队列中包含引用时,意味着引用指向的堆内存中的对象被回收。内存
构建缓存资源
使用软引用能够用于建立 Java 本地高速缓存,只要内存仍然够用缓存就不会被删除,而一旦内存紧张即将溢出时,GC 会删除部分缓存释放内存。例如,建立比较耗时影响性能的数据对象、一段时间内能够重复使用的资源、不常变化的数据等,均可以使用软引用构建缓存,既能保证读取性能,又不会致使内存溢出。开发
WeakHashMap
WeakHashMap 是以弱引用键实现的哈希表。当 WeakHashMap 中的键再也不被强引用使用时,GC 下次回收垃圾时将回收此键。WeakHashMap 中的键被回收后,哈希表的条目也会被 GC 回收。所以,WeakHashMap 能够用于临时存储一些不须要长时间使用的对象,能够有效避免内存溢出。
Java 开发中最经常使用的引用是强引用,经过new建立对象获得强引用。强引用会阻止 GC 释放对象内存,长时间运行容易致使内存溢出。在开发中,对于强引用变量在使用完毕后应把值设置为 null 来帮助 GC 进行垃圾回收。在 Java 中还有另外三种引用类型,弱引用、软引用和虚引用。弱引用和软引用能够用于构建缓存和避免内存泄露,虚引用能够用于获知对象将被回收的通知并进行处理。
四种引用类型的对好比下:
原文地址:关于Java引用,你必须知道这些