一篇关于java引用的笔记。
java的引用类型共四种
1:强引用
2:软引用
3:弱引用
4:虚引用
什么是强引用?
在java中普遍情况下我们会直接new Object(); 这种写法来创建一个对象 这种写法通常就是所谓的强引用,强引用的特别之处在于 假设当前程序即将OOM 那么在OOM来临 JVM会保证进行一次GC 当GC遇到强引用的对象 宁愿OOM也不会去回收该对象。当然 我们可以手动对该对象置空 或者 超出作用域时 GC就会对这类对象进行回收。
//code
public static void main(String[] args) {
Object o = new Object();//一个强引用对象
o=null;//同样 gc来了 会回收
}
public static void test(){
//超出了作用域的对象 会被gc来临时
Object o = new Object();
}
什么是软引用?
在Java中 用SoftReference 关键字包裹的对象就是一个软引用比如
SoftReference<byte[]> softReference = new SoftReference(new byte[1024]);///这是一个软引用对象
软引用对象的特点是 在JVM即将OOM前 JVM会保证进行一次GC 那么当GC遇到当前对象只剩软引用的话 就会对它进行回收 通俗的说 一个对象只能软引用引用的话 就会在内存不足的情况下被回收
SoftReference<byte[]> softReference = new SoftReference(new byte[1024]);
System.out.println(softReference.get().length);
///假设我们再创建bytes对象时 内存不足了 这个时候 JVM会让GC干活 GC扫描到软引用对象 就会回收
byte[] bytes = new byte[1024];
System.out.println(softReference.get());//这个时候 再次 get 就会为空
为了更好理解只剩一个对象引用
byte[] b = new byte[1024];
SoftReference<byte[]> softReference = new SoftReference(b);
System.out.println(softReference.get().length);
///假设我们再创建bytes对象时 这个时候 由于b对象不是只有一个引用 它有一个强引用 和一个软引用 我们的内存不足以创建 bytes时 就会触发OOM
byte[] bytes = new byte[1024];
什么是弱引用?
弱引用是一个比软引用还是"软"的引用 软引用可以看成是 弱引用的plus版本。 弱引用的特点是:当对象只剩一个弱引用对象时 任何时候 GC只要一遇到弱引用对象 就会对它进行回收。
WeakReference<byte[]> weakReference = new WeakReference(new byte[1024]);
System.out.println(weakReference.get().length);
System.gc();
System.out.println(weakReference.get());/// null 因为被gc了
什么是虚引用?
虚引用是四大引用中最弱的一种 它有一个特点 就是 无法通过get方法获取引用的对象
public class PhantomReference<T> extends Reference<T> {
public T get() {
return null;///get 方法 永远返回的是null。所以我们无法获取对象
}
public PhantomReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
}
}
而且虚引用在创建时 必须需要传入一个ReferenceQueue(引用队列) 而这个引用队列 会在对象销毁时 添加到这个队列里。
java中就时用虚引用管里堆外内存的 。( 知识点来自:马士兵java)
引用的特例
在之前测试时 为发现一个非常基础的知识被我遗忘了
WeakReference<Integer> wr1 = new WeakReference(new Integer(123));
WeakReference<Integer> wr2 = new WeakReference(123);
System.gc();
System.out.println(wr1.get());//会打印出null
System.out.println(wr2.get());//会打印出123
如果你不知道为什么 可能需要继续往下看
其实很简单 在Java中 有缓存池的概念。一些常用的基础类型 会存储在这些缓存池中 比如说下面类型:
String str = "123";//java会在字符串缓存池 寻找相同的 如果没有就创建 有的直接引用
int i = 123;// int 会缓存 -128 到 127 间的所有数字
byte;//会缓存所有的byte
boolean; //同样会缓存所有的值 当然 也只有false true