Object obj = new Student();
上面这块代码就是强引用,当你不在使用的时候才会进行GC。什么是再也不使用了,有如下二状况:
1 obj = null
2 当前方法执行完毕java
public static void main(String[] args) { SoftReference<Stu> s1 = soft(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); SoftReference<Stu> s2 = soft(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); SoftReference<Stu> s3 = soft(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); SoftReference<Stu> s4 = soft(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); SoftReference<Stu> s5 = soft(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); } public static SoftReference<Stu> soft(){ Stu s1 = new Stu(); s1.a1 = new int[1024*1024]; SoftReference<Stu> soft1 = new SoftReference<>(s1); System.out.println("total:"+Runtime.getRuntime().totalMemory()/1024/1024); System.out.println("max:"+Runtime.getRuntime().maxMemory()/1024/1024); System.out.println("free:"+Runtime.getRuntime().freeMemory()/1024/1024); return soft1; }
运行上面的程序,设置-Xms20m -Xmx20m,因为int占4个字节,所以执行到S5的时候,若是是强引用的话,就会抛内存溢出的异常。可是若是是软引的话,会在分配S5的时候,对S1进行回收,程序运行结果以下:code
total:19 max:19 free:14 当前对象是否被回收:false total:19 max:19 free:10 当前对象是否被回收:false total:19 max:19 free:6 当前对象是否被回收:false total:19 max:19 free:2 当前对象是否被回收:false total:19 max:19 free:14 当前对象是否被回收:true
public static void main(String[] args) { WeakReference<Stu> s1 = weak(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); WeakReference<Stu> s2 = weak(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); WeakReference<Stu> s3 = weak(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); WeakReference<Stu> s4 = weak(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); WeakReference<Stu> s5 = weak(); System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null)); } public static WeakReference<Stu> weak(){ Stu s1 = new Stu(); s1.a1 = new int[1024*1024]; WeakReference<Stu> weak = new WeakReference<>(s1); System.out.println("total:"+Runtime.getRuntime().totalMemory()/1024/1024); System.out.println("max:"+Runtime.getRuntime().maxMemory()/1024/1024); System.out.println("free:"+Runtime.getRuntime().freeMemory()/1024/1024); return weak; }
直接看执行结果:orm
total:19 max:19 free:14 当前对象是否被回收:false total:19 max:19 free:14 当前对象是否被回收:true total:19 max:19 free:14 当前对象是否被回收:true total:19 max:19 free:14 当前对象是否被回收:true total:19 max:19 free:14 当前对象是否被回收:true
虚引用主要用来清理对象用的,相似于对象的finalize方法。对象
public static void main(String[] args) throws InterruptedException { ReferenceQueue<Stu> queue = new ReferenceQueue<>(); Map<PhantomReference<Stu>,PhantomReference<Stu>> map = new HashMap<>(); PhantomReference<Stu> s1 = phantom(queue); map.put(s1,s1); recycle(queue,map); System.out.println(String.format("当前对象是否被回收:%s",map)); s1 = phantom(queue); map.put(s1,s1); recycle(queue,map); System.out.println(String.format("当前对象是否被回收:%s",map)); s1 = phantom(queue); map.put(s1,s1); recycle(queue,map); System.out.println(String.format("当前对象是否被回收:%s",map)); s1 = phantom(queue); map.put(s1,s1); recycle(queue,map); System.out.println(String.format("当前对象是否被回收:%s",map)); s1 = phantom(queue); map.put(s1,s1); recycle(queue,map); System.out.println(String.format("当前对象是否被回收:%s",map)); } public static void recycle( ReferenceQueue<Stu> queue,Map<PhantomReference<Stu>,PhantomReference<Stu>> map){ PhantomReference<Stu> phantom = null; while((phantom = (PhantomReference<Stu>)queue.poll()) != null){ System.out.println(phantom); map.remove(phantom); } } public static PhantomReference<Stu> phantom(ReferenceQueue<Stu> que){ Stu s1 = new Stu(); s1.a1 = new int[1024*1024]; PhantomReference<Stu> phantom = new PhantomReference<>(s1,que); System.out.println("total:"+Runtime.getRuntime().totalMemory()/1024/1024); System.out.println("max:"+Runtime.getRuntime().maxMemory()/1024/1024); System.out.println("free:"+Runtime.getRuntime().freeMemory()/1024/1024); return phantom; }
虚引用与软引用和弱引用不一样,第一次回收的时候,只是将对象加入到引用队列,并无真正清楚对象,虚引用须要将引用置空,才会回收整个对象,这也是与软引用与弱引用不一致的地方,如下执行结果:队列
total:19 max:19 free:14 当前对象是否被回收:{java.lang.ref.PhantomReference@a881b5=java.lang.ref.PhantomReference@a881b5} total:19 max:19 free:10 java.lang.ref.PhantomReference@a881b5 当前对象是否被回收:{java.lang.ref.PhantomReference@84aee7=java.lang.ref.PhantomReference@84aee7} total:19 max:19 free:6 java.lang.ref.PhantomReference@84aee7 当前对象是否被回收:{java.lang.ref.PhantomReference@9ee92=java.lang.ref.PhantomReference@9ee92} total:19 max:19 free:2 当前对象是否被回收:{java.lang.ref.PhantomReference@f39991=java.lang.ref.PhantomReference@f39991, java.lang.ref.PhantomReference@9ee92=java.lang.ref.PhantomReference@9ee92} total:19 max:19 free:6 当前对象是否被回收:{java.lang.ref.PhantomReference@f39991=java.lang.ref.PhantomReference@f39991, java.lang.ref.PhantomReference@12b3a41=java.lang.ref.PhantomReference@12b3a41, java.lang.ref.PhantomReference@9ee92=java.lang.ref.PhantomReference@9ee92}
若是map不执行remove方法的话,会报内存溢出。内存
软引用,弱引用与虚引用中的对象,若是有强引用是不可以被回收的。rem