【Java】Java中的四种对象引用
1.强引用(StrongReference)
String strong = new String("Strong Reference")
,当一个实例对象具有强引用时,垃圾回收器不会回收该对象,当内存不足时,宁愿抛出OutOfMemeryError异常也不会通过回收强引用的对象,因为JVM认为强引用的对象是用户正在使用的对象,它无法分辨出到底该回收哪个,强行回收有可能导致系统严重错误。2.软引用(SoftRefernce)
ReferenceQueue referenceQueue = new ReferenceQueue();
SoftReference<Book> softReference = new SoftReference<>(new Book(), referenceQueue);
Book book = softReference.get();
Reference reference = referenceQueue.poll();
当系统内存不足时,触发gc,这个Book就会被回收,reference 将不为null。
3.弱引用(WeakReference)
ReferenceQueue referenceQueue = new ReferenceQueue();
WeakReference<Book> weakReference = new WeakReference(new Book(), referenceQueue);
Book book = softReference.get();
System.gc();
//Runtime.getRuntime().gc();
Reference reference = referenceQueue.poll();
当然这不是每次都能复现,因为我们调用System.gc()只是告诉JVM该回收垃圾了,但是它什么时候做还是不一定的,但就我测试来看,只要多写几次System.gc(),复现的概率还是很高的。
PS,
ThreadLocalMap中的静态内部类Entry类就是继承了WeakRefence<ThreadLocal>这个类在构造方法中
static class ThreadLocalMap { static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value; Entry(ThreadLocal<?> k, Object v) {
//调用父类WeakReference的构造方法
super(k);
value = v;
}
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
//ThreadLocalMap将ThreadLocal作为key,(注意这个Key有点特殊,这个Key被弱引用关联)
map.set(this, value);
else
createMap(t, value);
}
private void set(ThreadLocal<?> key, Object value) { // We don't use a fast path as with get() because it is at
// least as common to use set() to create new entries as
// it is to replace existing ones, in which case, a fast
// path would fail more often than not. Entry[] tab = table;
int len = tab.length;
int i = key.threadLocalHashCode & (len-1); for (Entry e = tab[i];
e != null;
e = tab[i = nextIndex(i, len)]) {
//e最终获取的是其实是被弱引用WeakRerference关联的ThreadLocal
ThreadLocal<?> k = e.get(); if (k == key) {
e.value = value;
return;
} if (k == null) {
replaceStaleEntry(key, value, i);
return;
}
} tab[i] = new Entry(key, value);
int sz = ++size;
if (!cleanSomeSlots(i, sz) && sz >= threshold)
rehash();
}
//Reference中的Get方法
public T get() {
return this.referent;
}
注意:
由于Thread 线程对象都具有成员变量ThreadLocal.ThreadLocalMap,
而ThreadLocalMap中的key就是当前ThreadLocal对象,而value就是我们想要和线程上下文绑定的数据,
同时ThreadLocal又被弱引用关联,
因此在线程生命周期结束时,其成员变量ThreadLocal.ThreadLocalMap,也会为null,此时内部的Entry会做额外的操作将value置为null,
这样就满足了弱引用被回收的条件:当且仅当Entry的key持有弱引用时,该ThreadLocal就会被回收,解决了ThreadLocal对象内存泄漏的问题;
4.虚引用(PhantomReference)
PhantomReference<Book> phantomReference = new PhantomReference<>(new Book(), referenceQueue);
Book book = phantomReference.get(); //此值为null
Reference reference = referenceQueue.poll();
【Java】Java中的四种对象引用的更多相关文章
- JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)
1.throws和throw的区别 throws使用在函数外,是编译时的异常,throw使用在函数内,是运行时的异常 使用方法 public int method(int[] arr) throws ...
- JAVA中的四种引用以及ReferenceQueue和WeakHashMap的使用示例
简介: 本文主要介绍JAVA中的四种引用: StrongReference(强引用).SoftReferenc(软引用).WeakReferenc(弱引用).PhantomReference(虚引用) ...
- Java中的四种引用
引用定义 实际上,Java中存在四种引用,它们由强到弱依次是:强引用.软引用.弱引用.虚引用.下面我们简单介绍下这四种引用: 强引用(Strong Reference):通常我们通过new来创建一个新 ...
- JAVA中的四种JSON解析方式详解
JAVA中的四种JSON解析方式详解 我们在日常开发中少不了和JSON数据打交道,那么我们来看看JAVA中常用的JSON解析方式. 1.JSON官方 脱离框架使用 2.GSON 3.FastJSON ...
- java 20 -10 字节流四种方式复制mp3文件,测试效率
电脑太渣,好慢..反正速率是: 高效字节流一次读写一个字节数组 > 基本字节流一次读写一个字节数组 > 高效字节流一次读写一个字节 > 基本字节流一次读写一个字节 前两个远远快过后面 ...
- Java通过Executors提供四种线程池
http://cuisuqiang.iteye.com/blog/2019372 Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果 ...
- JAVA解析XML的四种方式
java解析xml文件四种方式 1.介绍 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这 ...
- 【Java】详解Java解析XML的四种方法
XML现在已经成为一种通用的数据交换格式,平台的无关性使得很多场合都需要用到XML.本文将详细介绍用Java解析XML的四种方法. AD: XML现在已经成为一种通用的数据交换格式,它的平台无关性,语 ...
- java环境变量配置四种方法
原文:java环境变量配置四种方法 Java编程首要工作就是安装JDK(Java Development Kit).一通“NEXT”点完安装后就是最重要的环境变量设置了.也许有人会问为什么要设置环境变 ...
随机推荐
- 二叉树、平衡二叉树、红黑树、B树、B+树与B*树
转: 二叉树.平衡二叉树.红黑树.B树.B+树与B*树 一.二叉树 1️⃣二叉查找树的特点就是左子树的节点值比父亲节点小,而右子树的节点值比父亲节点大,如图: 基于二叉查找树的这种特点,在查找某个节点 ...
- c++移动构造
下面随笔给出c++移动构造. 在现实中有很多这样的例子,我们将钱从一个账号转移到另一个账号,将手机SIM卡转移到另一台手机,将文件从一个位置剪切到另一个位置--移动构造可以减少不必要的复制,带来性能上 ...
- 微信小程序封装请求接口
var rootDocment = 'https://123.com';//你的域名 function postData(url, data, cb) { wx.request({ url: root ...
- TorchVision Faster R-CNN 微调,实战 Kaggle 小麦检测
本文将利用 TorchVision Faster R-CNN 预训练模型,于 Kaggle: 全球小麦检测 上实践迁移学习中的一种常用技术:微调(fine tuning). 本文相关的 Kaggle ...
- 24端口以太网FPGA的开发板
板卡架构 板载FPGA(K7-325T)处理24端口10/100/1000M以太网数据: FPGA外挂4Gbit的DDR3颗粒,最大支持800MHz: 板载CPU进行系统配置.管理,并与客户端软件通信 ...
- WPF 基础 - 属性
1. CLR 属性 .Net Framework 中的属性又称为 CLR 属性,是对 private 字段的安全访问包装. 使用 ILSpy 反编译器可以看到 C# 中代码的属性的编译结果是 set. ...
- 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: 输 ...
- Python之基础算法介绍
一.算法介绍 1. 算法是什么 算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输 ...
- 多线程之volative关键字
目录 轻量级同步机制:volative关键字 volative的作用 volatile非原子特性 volatile与synchronized比较 常用原子类进行自增自减操作 CAS 使用CAS原理实现 ...
- frida hook_RegisterNatives--使用frida打印so中动态注册的函数
原文地址:https://github.com/lasting-yang/frida_hook_libartfrida -U --no-pause -f package_name -l hook_Re ...