Java 中类型可分为两大类:值类型与引用类型。值类型就是基本数据类型(如int ,double 等),而引用类型,是指除了基本的变量类型之外的所有类型(如通过 class 定义的类型)。所有的类型在内存中都会分配一定的存储空间(形参在使用的时候也会分配存储空间,方法调用完成之后,这块存储空间自动消失), 基本的变量类型只有一块存储空间(分配在stack中), 而引用类型有两块存储空间(一块在stack中,一块在heap中)。
在Java中提供了四种引用类型分别是:
强引用
特点:
- 强引用可以直接访问目标对象。
- 强引用所指向的对象在任何时候都不会被系统回收。JVM宁愿抛出OOM异常,也不会回收强引用所指向的对象。
- 强引用可能导致内存泄漏。
举例:
StringBuffer stringBuffer = new StringBuffer("Helloword");
软引用
特点:
它的一个实例保存对一个Java对象的软引用, 该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。
在垃圾线程对 这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。
举例:
SoftReference<String> softRef=new SoftReference<String>(str);
弱引用
弱引用是一种比软引用较弱的引用类型。在系统GC时,只要发现弱引用,不管系统堆空间是否足够,都会将对象进行回收。在java中,可以用java.lang.ref.WeakReference实例来保存对一个Java对象的弱引用。
举例:
public void test3(){
MyObject obj = new MyObject();
WeakReference sf = new WeakReference(obj);
obj = null;
System.out.println("是否被回收"+sf.get());
System.gc();
System.out.println("是否被回收"+sf.get());
}
虚引用
虚引用是所有类型中最弱的一个。一个持有虚引用的对象,和没有引用几乎是一样的,随时可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程。
举例:
public void test3(){
MyObject obj = new MyObject();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference sf = new PhantomReference<>(obj,referenceQueue);
obj = null;
System.out.println("是否被回收"+sf.get());
System.gc();
System.out.println("是否被回收"+sf.get());
}
结果:
是否被回收null
是否被回收null