1)强引用。强引用是最普遍的,当一个对象有强引用的的时候,其不会被gc回收,不管内存足够还是不足够。
2)软引用。SoftReference类,类内包含指定对象的引用,当一个对象只有软引用的且内存不足的时候,对象会被gc回收,可以配合ReferenceQueue队列使用,若对象被回收,则会把SoftReference内指定对象的引用置为null,SoftReference对象会进入ReferenceQueue,通过对ReferenceQueue使用poll方法来判断指定对象是否被gc回收。
3)弱引用。WeakReference类,类内包含指定对象的引用,当一个对象只有弱引用的时候,不管内存足还是不足,都会gc回收,可以配合ReferenceQueue队列使用,通过对ReferenceQueue使用poll方法来判断指定对象是否被gc回收,第一次回收会被标记为垃圾回收,用get有可能获取到对象,第二次gc会被回收,用get返回空。当弱引用的指向对象变得弱引用可到达,该弱引用就会加入到引用队列。这一操作发生在对象析构或者垃圾回收真正发生之前,可以在不规范的finalize方法里重新添加指向对象的引用,复活对象。
4)虚引用。PhantomReference类,当一个对象只有弱引用的时候,任何时候都会被gc回收。通过get获取永远都为空。虚引用用来判断和跟踪对象是否被回收,而且必须和ReferenceQueue联合使用。虚引用可以避免很多析构方法带来的问题。重写析构函数,gc第一次会标记其为垃圾,因为调用析构函数的线程优先级是很低的,故不知道需要经过多少个gc周期才能回收到对象,这就容易发生内存泄漏,使用虚引用则可以判断对象是否真正被gc回收,避免这个问题。
II、java引用的场景
1)因为软引用的特性,在内存不足的时候才去回收只有软引用指向的对象,故适合做高速缓存,当用户去访问 某些数据时,从数据库里拉回数据后,建立软引用会缓存那些经常去查询的数据(很少改动,如新闻,文章等),当用户再次去访问的时候,就从缓存里获取,不必再从数据库里获取。
2)弱引用
其中一个应用场景是当应用实现了自定义的classLoader,当没有对象指向classLoader的时候,则回收classLoader。