JAVA不可不知的强软弱虚四种引用
2024-10-20 15:49:17
一个变量指向new对象,就是引用,在java中有四种引用,分别是强软弱虚,常见的Object o = new Object(),就是强引用,垃圾回收的时候,强引用不会被回收。
- 公用类:
public class M {
@Override
protected void finalize() throws Throwable {
System.out.println("finalize");
}
} - 强:只要有引用就不会回收代码:
public class T01_NormalReference {
public static void main(String[] args) throws IOException {
M m = new M();
m = null;//只有没有引用时,M的对象m才会被回收
System.gc(); //DisableExplicitGC
System.in.read();//阻塞线程的目的是:因为GC是运行在其他线程中的,不阻塞很可能还没开始回收,线程就已经结束了。
}
}
- 软:空间不够才回收,用于缓存
代码:先设置VM options :-Xms20M -Xmx20M(设置堆内存最大最小都是20M)public class T02_SoftReference {
public static void main(String[] args) {
SoftReference<byte[]> m = new SoftReference<>(new byte[1024*1024*10]);
//m = null;
System.out.println(m.get());
System.gc();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(m.get());
//再分配一个数组,heap将装不下,这时候系统会垃圾回收,先回收一次,如果不够,会把软引用干掉,此时打印的结果应该是空置
byte[] b = new byte[1024*1024*15];
System.out.println(m.get());
}
} - 弱引用:只要调用了垃圾回收(System.gc())就回收,应用场景:只要强引用消失,则应该被回收,一般用在容器里,典型应用ThreadLock,看下WeakHashMap、AQSunlock源码(Tomcat缓存用的是弱应用)
代码:public class T03_WeakReference {
public static void main(String[] args) {
WeakReference<M> m = new WeakReference<>(new M());
System.out.println(m.get());
System.gc();
System.out.println(m.get());
ThreadLocal<M> tl = new ThreadLocal<>();
tl.set(new M());
tl.remove();//必须ThreadLocal用完必须remove,否则还是有内存泄漏
}
} - 弱引用举例子程序
public class ThreadLocal2 {
static ThreadLocal<Person> tl = new ThreadLocal<>();
public static void main(String[] args) { new Thread(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
tl.set(new Person());
}).start();
}
static class Person {
String name = "zhangsan";
}
}例子图示:
- 虚引用,主要用于对外内存。一般是搞JVM的人用,所以基本没用。
1、堆外内存。
NIO里面有一个Buffer,叫DirectByteBuffer(直接内存,不被jvm虚拟机管理),也叫堆外内存,被操作系统管理,如果这个引用被置为空值,则没法回收,用虚引用
时,检测Queue,如果被回收了则去清理堆外内存。java回收堆外内存用的是Unsave中的freeMemory
2、会关联一个队列,当虚引用被回收的时候回接收到关联队列里,也就是给你一个通知,被回收了,弱引用里面的值是可以get到的,虚引用根本get不到
3、垃圾回收器一过来,直接就被回收了 - 验证程序(先设置堆内存为20M,VM options :-Xms20M -Xmx20M,生产环境中堆空间最大最小设置成一样)
public class T04_PhantomReference {
private static final List<Object> LIST = new LinkedList<>();
private static final ReferenceQueue<M> QUEUE = new ReferenceQueue<>();
public static void main(String[] args) {
PhantomReference<M> phantomReference = new PhantomReference<>(new M(), QUEUE);
new Thread(() -> {
while (true) {
LIST.add(new byte[1024 * 1024]);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
System.out.println(phantomReference.get());
}
}).start();
new Thread(() -> {
while (true) {
Reference<? extends M> poll = QUEUE.poll();
if (poll != null) {
System.out.println("--- 虚引用对象被jvm回收了 ---- " + poll);
}
}
}).start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
最新文章
- 破解Xamarin
- Interview----求 1+2+...+n, 不能用乘除法、for、while if、else、switch、case 等关键字以及条件判断语句 (A?B:C)
- 【转】JDBC为什么要使用PreparedStatement而不是Statement
- POJ C程序设计进阶 编程题#6:流感传染
- Android开发技巧:像QQ一样输入表情图像
- JavaScript之String()和.toString()
- Contest 高数题 樹的點分治 樹形DP
- java.util 中的property
- Learning Lua Programming (3) iMac下搭建Lua脚本最好的编码环境(代码补全,编译运行)
- 新一代分布式任务调度框架:当当elastic-job开源项目的10项特性
- 经常使用的正則表達式归纳—JavaScript正則表達式
- 201521123074 《Java程序设计》第12周学习总结
- java.sql.Exception:setString 只能处理少于 32766 个字符的字符串
- 从Scratch到Python之角色与造型
- Gym - 100989E
- 免费API 接口罗列,再也不愁没有服务器开发不了APP了(下)【申明:来源于网络】
- HDU5543(SummerTrainingDay03-O DP)
- 编写一个JavaWeb项目
- 12 文件查找--find命令
- linux下修改root密码以及找回密码的方法