强引用不会被GC回收,并且在java.lang.ref里也没有实际的对应类型。举个例子来说:
Object obj = new Object();
这里的obj引用便是一个强引用,不会被GC回收。
/**
* @Description: 强引用
*
* 设置堆最大内存128M,超出将OutOfMemoryError
* @Date: 2018/11/12 0:01
*/
public class StrongReference {
public static void main(String[] args) {
int i =0;
List list = new ArrayList<>();
for (;;){
int i1 = i++;
Ref ref = new Ref(i1);
list.add(ref);
System.out.println(i1 + "加到list中");
}
}
private static class Ref{
private byte[] bytes = new byte[1024*1024];//1M
private final int index;
private Ref(int index) {
this.index = index;
}
@Override
protected void finalize() throws Throwable {
System.out.println("--index---" + index + "---将要GC");
}
}
}
当堆内存满时,将OutOfMemoryError.
软引用在JVM报告内存不足的时候才会被GC回收,否则不会回收,正是由于这种特性软引用在caching和pooling中用处广泛。软引用的用法:
Object obj = new Object();
SoftReference
/**
*SoftReference(软引用):
* 当发生GC(MinorGC/FullGC)时,当检测到JVM内存快要满了,将GC Soft Reference
*
* SoftReference可能会OutOfMemoryError
* 1.当我们把睡眠时间调制1ms时,会报OutOfMemoryError
* 2.当我们把睡眠时间调制1s时,程序会一直执行下去,可以看到对象被GC
* 分析:时间调至1ms,这时还未来得及GC,又放入,会出现堆内存溢出
* 当1s时,有足够的时间去GC.不会全部GC掉
* 总结:在缓存中,一般放的次数远远小于放的次数,不可能不断地放入缓存,因此用SoftReference,绝大多时候
* 不会报OutOfMemoryError
*
*
*/
public class Soft_Reference {
public static void main(String[] args) throws InterruptedException {
int i =0;
List> list = new ArrayList<>();
for (;;){
int i1 = i++;
list.add(new SoftReference<>(new Ref(i1)));
System.out.println(i1 + "加到list中");
TimeUnit.MILLISECONDS.sleep(1000);
}
}
private static class Ref{
private byte[] bytes = new byte[1024*1024];//1M
private final int index;
private Ref(int index) {
this.index = index;
}
@Override
protected void finalize() throws Throwable {
System.out.println("--index---" + index + "---将要GC");
}
}
}
当GC一但发现了弱引用对象,将会释放WeakReference所引用的对象
/**
*WeakReference(弱引用):
* 当发生GC(MinorGC/FullGC)时,都会被回收掉。
*/
public class Weak_Reference {
public static void main(String[] args) throws InterruptedException {
int i =0;
List> list = new ArrayList<>();
for (;;){
int i1 = i++;
list.add(new WeakReference<>(new Ref(i1)));
System.out.println(i1 + "加到list中");
TimeUnit.MILLISECONDS.sleep(100);
}
}
private static class Ref{
private byte[] bytes = new byte[1024*1024];//1M
private final int index;
private Ref(int index) {
this.index = index;
}
@Override
protected void finalize() throws Throwable {
System.out.println("--index---" + index + "---将要GC");
}
}
}
当GC一但发现了虚引用对象,将会将PhantomReference对象插入ReferenceQueue队列,而此时PhantomReference所指向的对象并没有被GC回收,而是要等到ReferenceQueue被你真正的处理后才会被回收。虚引用的用法:
Object obj = new Object();
ReferenceQueue
虚引用在实现一个对象被回收之前必须做清理操作是很有用的。有时候,他们比finalize()方法更灵活。
很明显的,虚引用可以用来做对象被回收之前的清理工作。
//TODO
对于Reference先介绍到这,能力有限,后面再继续补充.
参考:https://blog.csdn.net/aitangyong/article/details/39453365