强软弱引用,ThreadLocal和内存泄漏
强引用
写法:Object obj=new Object()
引用强度:最强
只要被引用着,就不会被gc(垃圾回收)回收掉。
软引用
写法:SoftReference<String> sr = new SoftReference<String>(new String("软"));
引用强度:第二
如果内存不足时,就会回收掉软引用,适用于缓存。
弱引用
写法:WeakReference<String> wr = new WeakReference<String>(new String("弱"));;
引用强度:第三
当JVM进行垃圾回收的时候,无论内存是否充足都会将其回收掉。
ThreadLocal简介
ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量,例如A线程给类对象赋值在A线程中可以输出,在B线程中再去输出这个对象的值就会是null。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
ThreadLocal源码
set方法
public void set(T value) {
//获取到当前线程
Thread t = Thread.currentThread();
//从当前线程获取Map
ThreadLocalMap map = getMap(t);
if (map != null)
//如果当前map不为空继续存,this为ThreadLocal对象,value就是传进来的值
map.set(this, value);
else
//为空就创建一个新的ThreadLocalMap
createMap(t, value);
}
map.set方法中
private void set(ThreadLocal<?> key, Object value) {
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)]) {
ThreadLocal<?> k = e.get();
if (k == key) {
e.value = value;
return;
}
if (k == null) {
replaceStaleEntry(key, value, i);
return;
}
}
//可以理解为一个Entry就等于一个键值对
tab[i] = new Entry(key, value);
int sz = ++size;
if (!cleanSomeSlots(i, sz) && sz >= threshold)
rehash();
}
Entry方法
//继承了弱引用
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
//调用了父类的构造
super(k);
value = v;
}
}

ThreadLocal之内存泄漏
内存泄漏:是指一个用不到对象在内存中强引用着,也清理不掉,无法释放就会占用内存资源。
内存溢出:是指一直在内存中存放强引用对象,也回收不掉就会存放满导致溢出。
为什么ThreadLocal的Entry是弱引用?因为如果是强引用,即使ThreadLocal local = null,但key依然指向ThreadLocal对象,ThreadLocal对象不会被回收,导致内存泄漏。而弱引用,ThreadLocal对象会被回收掉。但是,ThreadLocal对象被回收掉,key = null,value永远不会被访问到,所以依然存在内存泄漏的问题。解决方法是,使用ThreadLocal.set设置值,使用完之后,要调用remove方法移除。
ThreadLocal应用场景
ThreadLocal在Spring框架中,用于实现声明式事务。开启事务后,将从连接池中拿到的数据库连接,存放到ThrealLocal中,保证事务中的所有数据库操作都是从ThreadLocal中拿到同一个数据库连接。
强软弱引用,ThreadLocal和内存泄漏的更多相关文章
- ThreadLocal以及内存泄漏
ThreadLocal是什么 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用Thr ...
- iOS - Block产生Memory Leaks循环引用导致的内存泄漏以及解决方案
在ARC(自动引用技术)前,Objective-c都是手动来分配释放 释放 计数内存,其过程非常复杂. ARC技术推出后,貌似世界和平了很多,但是其实ARC并不等同于Java或者C#中的垃圾回收,AR ...
- 通过weakHashMap避免过期引用导致的内存泄漏
问题由来 数组为基础实现的集合在退出元素时,并不会将引用指向空指针,过期引用存在对象便不会被回收. 措施 1.WeakHashMap当其中的key没有再被外部引用时,就会被回收.ThreadLocal ...
- 深入分析 ThreadLocal 内存泄漏问题
前言 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用ThreadLocal,就可能 ...
- 分析 ThreadLocal 内存泄漏问题
ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用 ThreadLocal,就可能会导 ...
- java多线程--------深入分析 ThreadLocal 内存泄漏问题
前言 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用ThreadLocal,就可能 ...
- 18.一篇文章,从源码深入详解ThreadLocal内存泄漏问题
1. 造成内存泄漏的原因? threadLocal是为了解决对象不能被多线程共享访问的问题,通过threadLocal.set方法将对象实例保存在每个线程自己所拥有的threadLocalMap中,这 ...
- ThreadLocal内存泄漏真因探究(转)
出处: 链接:https://www.jianshu.com/p/a1cd61fa22da ThreadLocal原理回顾 ThreadLocal的原理:每个Thread内部维护着一个ThreadLo ...
- ThreadLocal 内存泄漏问题深入分析
写在前面 ThreadLocal 基本用法本文就不介绍了,如果有不知道的小伙伴可以先了解一下,本文只研究 ThreadLocal 内存泄漏这一问题. ThreadLocal 会发生内存泄漏吗? 先给出 ...
- 【知识必备】内存泄漏全解析,从此拒绝ANR,让OOM远离你的身边,跟内存泄漏say byebye
一.写在前面 对于C++来说,内存泄漏就是new出来的对象没有delete,俗称野指针:而对于java来说,就是new出来的Object放在Heap上无法被GC回收:而这里就把我之前的一篇内存泄漏的总 ...
随机推荐
- 区块相隔虽一线,俱在支付同冶熔,Vue3.0+Tornado6前后端分离集成Web3.0之Metamask区块链虚拟三方支付功能
最近几年区块链技术的使用外延持续扩展,去中心化的节点认证机制可以大幅度改进传统的支付结算模式的经营效率,降低交易者的成本并提高收益.但不能否认的是,区块链技术也存在着极大的风险,所谓身怀利器,杀心自起 ...
- 02_Django-路由配置-HTTP协议的请求和响应
02_Django-路由配置-HTTP协议的请求和响应 视频:https://www.bilibili.com/video/BV1vK4y1o7jH 博客:https://blog.csdn.net/ ...
- day33-线程基础03
线程基础03 6.用户线程和守护线程 用户线程:也叫工作线程,当线程的任务执行完或者通知方法结束.平时用到的普通线程均是用户线程,当在Java程序中创建一个线程,它就被称为用户线程 守护线程(Daem ...
- KingbaseES 全局索引
概述:在分区表上创建的索引可分为全局索引和本地索引.全局索引包括全局非分区索引(Global Nonpartitioned Indexes)和全局分区索引(Global Partitioned Ind ...
- 004-GoingDeeperConvolutions2014(googLeNet)
Going Deeper with Convolutions #paper 1. paper-info 1.1 Metadata Author:: [[Christian Szegedy]], [[W ...
- getch()之隐藏输入密码
getch() :读取字符且不会回显(不会显示):不从输入缓冲区读取:在getch中,把回车按键输入, 识别为回车符'\r':在getchar中,把回车按键输入,识别为回车符'\n'. getch() ...
- .NET 反向代理-YARP 根据域名转发
前段时间发布过一个关于 YARP 的简单介绍,感兴趣的小伙伴恭请移步看看 .NET 反向代理-YARP - 一事冇诚 - 博客园 (cnblogs.com) 作为反向代理,必不可少的当然是根据域名代理 ...
- Prometheus 监控 Kubernetes Job 资源误报的坑
转载自:https://www.qikqiak.com/post/prometheus-monitor-k8s-job-trap/ 昨天在 Prometheus 课程辅导群里面有同学提到一个问题,是关 ...
- 11. 第十篇 网络组件flanneld安装及使用
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483834&idx=1&sn=b04ec193 ...
- es证书生成方式
./bin/elasticsearch-certutil ca --pem # 生成一个名字叫做elastic-stack-ca.zip的文件 unzip elastic-stack-ca.zip A ...