在JDK1.2版之后,Java对引用的概念进行了扩充,将引用分为强引用(Strongly Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)4种,Java中4种引用的级别由高到低依次为:强引用 > 软引用 > 弱引用 > 虚引用.
1.强引用(Strongly Reference)
“永远不会回收掉被引用的对象”
在 Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引
用, 即类似“Object obj=new Object()”这种引用关系。
当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到 JVM 也不会回收。因此强引用是造成 Java 内存泄漏的主要原因之一。
class A{
public void say(){
System.out.println("hello");
}
}
public class Solution {
public static void main(String[] args){
//强引用
A a = new A();
a.say();
}
}
2.软引用(Soft Reference)
“内存不够就回收,内存充足不回收”
“适合做缓存”
软引用需要用 SoftReference 类来实现,对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中。
1、引用和对象通过SoftReference建立关联, 例如:SoftReference a = new SoftReference(new A());
2、当系统内存够用就保留不回收(即使发生了GC),内存不足时,会被回收
3、软引用自身不会被垃圾回收,因为GC Root还引用着,软引用自身需要配合引用队列来释放。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
4、软引用适合缓存使用的场景,当内存不够的时候,对象是被回收的。
class A{
public void say(){
System.out.println("hello");
}
}
public class Solution {
public static void main(String[] args){
//软引用
SoftReference<A> asr=new SoftReference<>(new A());
asr.get().say();
}
}
3.弱引用(Weak Reference)
“只要发生GC,一定被回收”
1、弱引用需要用 WeakReference 类来实现,例如:WeakReference a = new WeakReference(new A());
2、如果仅有弱引用引用该对象时,只要发生垃圾回收,就会释放该对象
3、当一个对象仅仅被弱引用指向, 而没有任何其他强引用指向的时候, 如果GC运行, 那么这个对象就会被回收。如果存在强引用同时与之关联,则进行垃圾回收时不会回收该对象。
4、ThreadLocal和WeakHashMap内部都是使用了弱引用,用来保证那些不被用到的key值,在垃圾回收的时候可以被回收掉。
class A{
public void say(){
System.out.println("hello");
}
}
public class Solution {
public static void main(String[] args){
//弱引用
WeakReference awr = new WeakReference(new A());
((A)awr.get()).say();
}
}
4.虚引用(Phantom Reference)
“发生GC时, 总会被回收”
1、 虚引用需要 PhantomReference 类来实现,它不能单独使用,必须和引用队列联合使用, 例如: PhantomReference a = new PhantomReference(new A(), referenceQueue);
2、当虚引用所引用的对象被回收时(a对象、b对象),由 Reference Handler 线程将虚引用对象入队,这样就可以知道哪些对象被回收,从而对它们关联的资源做进一步处理
3、 也称为幽灵引用或者幻影引用,它是最弱的引用关系。无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。虚引用的主要作用是跟踪对象被垃圾回收的状态。
4、被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收。