1.JAVA引用有四种
强引用 就是我们最常用的对象引用 String s = new String("");
SoftReference,
WeakReference
PhantomReference
FinalReference
2.先说说GC
2.1 先定义一个普通类 override finalliz 方法
finalize()函数是在JVM回收内存时执行的,但JVM并不保证在回收内存时一定会调用finalize()
public class NormalClass {
@Override
protected void finalize()throws Throwable {
super.finalize();
System.out.println("finalize gc is done");
}
}
2.2 写一个模拟内存内存溢出的类
public class OOM {
public OOM() {
}
public static void oom(){
String name ="hello";
for (int i =0; i <100000000; i++) {
name += name;
}
System.out.println(name);
}
}
3 测试类
第一种情况 清除对象 设置为null
public static void main(String[] args){
NormalClass normalClass =new NormalClass();
normalClass =null;
}
没有任何输出
原因 jvm gc 没有触发 我们知道gc是jvm自己控制的
第二种情况 System.gc()手工触发
public static void main(String[] args){
NormalClass normalClass =new NormalClass();
normalClass =null;
System.gc();
}
finalize gc is done
第三种情况 大量内存使用触发
public static void main(String[] args){
NormalClass normalClass =new NormalClass();
normalClass =null;
OOM.oom();
}
finalize gc is done
虽然我们没有手工触发,但是由于大量内存使用 导致jvm自己触发了GC
3 强引用
所谓的强引用就是我们最常用的对象引用
强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
我们用测试案例来理解这句话
public static void main(String[] args){
NormalClass normalClass =new NormalClass();
//normalClass = null;
OOM.oom();
}
gc 没有执行 finalize gc is done 没有输出
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
NormalClass对象的引用还在 并没有被置空
4 SoftReference
如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
我们用案例理解
public static void main(String[] args){
SoftReference ref =new SoftReference(new NormalClass()) ;
OOM.oom();
}
输出finalize gc is done
java.lang.OutOfMemoryError: Java heap space
public static void main(String[] args){
SoftReference ref =new SoftReference(new NormalClass()) ;
System.gc();
//OOM.oom();
}
输出 没有任何输出
内存够用 即使调用System.gc() 也没有被回收
5 WeakReference
弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
案例
public static void main(String[] args){
WeakReference ref =new WeakReference(new NormalClass()) ;
OOM.oom();
}
输出 finalize gc is done
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
public static void main(String[] args){
WeakReference ref =new WeakReference(new NormalClass()) ;
//OOM.oom();
System.gc();
}
输出 finalize gc is done
WeakReference 意思就是只有gc动作 WeakReference就顺带回收了