ThreadLocal笔记

如上图所示

每个Thread 都有一个map,里面存着Entry<Key,value>,而key是实现了WeakReferenceThreadLocal,如果不是WeakReference,那么可能Entry里面的key和value在线程结束才会进行GC,但是由于是WeakReference,因此当Key被设置为null时,key就会被 gc 回收.

但是由于value还在currentThread->Map->Entry->value中,因此导致了内存泄漏

解决方法

hreadLocalMap类的设计本身已经有了这一问题的解决方案,那就是在每次get()/set()/remove()ThreadLocalMap中的值的时候,会自动清理key为null的value。如此一来,value也能被回收了。

private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) {
Entry[] tab = table;
int len = tab.length; while (e != null) {
ThreadLocal<?> k = e.get();
if (k == key)
return e;
if (k == null)
expungeStaleEntry(i);
else
i = nextIndex(i, len);
e = tab[i];
}
return null;
}

中的

if (k == null)
expungeStaleEntry(i);

expungeStaleEntry保证了key为null的情况下value也置为null

private int expungeStaleEntry(int staleSlot) {
Entry[] tab = table;
int len = tab.length; // expunge entry at staleSlot
tab[staleSlot].value = null;
tab[staleSlot] = null;
size--; // Rehash until we encounter null
Entry e;
int i;
for (i = nextIndex(staleSlot, len);
(e = tab[i]) != null;
i = nextIndex(i, len)) {
ThreadLocal<?> k = e.get();
if (k == null) {
e.value = null;
tab[i] = null;
size--;
} else {
int h = k.threadLocalHashCode & (len - 1);
if (h != i) {
tab[i] = null; // Unlike Knuth 6.4 Algorithm R, we must scan until
// null because multiple entries could have been stale.
while (tab[h] != null)
h = nextIndex(h, len);
tab[h] = e;
}
}
}
return i;
}

ThreadLocal 的机制与内存泄漏的更多相关文章

  1. Chrome 浏览器垃圾回收机制与内存泄漏分析

    Chorme 浏览器中的垃圾回收和内存泄漏 垃圾回收 通常情况下,垃圾数据回收分为手动回收和自动回收两种策略. 手动回收策略,何时分配内存.何时销毁内存都是由代码控制的. 自动回收策略,产生的垃圾数据 ...

  2. ThreadLocal基本使用和内存泄漏分析

    ThreadLocal基础部分 ThreadLoal的作用 保存线程的独立变量,即每个线程维护一份.这种变量在线程的生命周期内起作用,减少同一个线程内多个函数之间公共变量传递麻烦. 使用场景 需要给不 ...

  3. JavaScript的垃圾回收机制与内存泄漏

    常用的两种算法: 引用计数(新版浏览器已弃用,弃用原因:会出现循环引用的情况,无法进行垃圾回收,导致内存泄漏) 标记清除 引用计数法 引用计数,顾名思义一个对象是否有指向它的引用,即看栈中是否有指向要 ...

  4. JS基础-垃圾回收机制与内存泄漏的优化

    [V8引擎]浅析Chrome V8引擎中的垃圾回收机制和内存泄露优化策略 垃圾回收机制 如何判断回收内容 如何确定哪些内存需要回收,哪些内存不需要回收,这是垃圾回收期需要解决的最基本问题.我们可以这样 ...

  5. 深入剖析ThreadLocal实现原理以及内存泄漏问题

    关于ThreadLocalMap<ThreadLocal, Object>弱引用问题: 当线程没有结束,但是ThreadLocal已经被回收,则可能导致线程中存在ThreadLocalMa ...

  6. ThreadLocal以及内存泄漏

    ThreadLocal是什么 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用Thr ...

  7. 18.一篇文章,从源码深入详解ThreadLocal内存泄漏问题

    1. 造成内存泄漏的原因? threadLocal是为了解决对象不能被多线程共享访问的问题,通过threadLocal.set方法将对象实例保存在每个线程自己所拥有的threadLocalMap中,这 ...

  8. 深入分析 ThreadLocal 内存泄漏问题

    前言 ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度.但是如果滥用ThreadLocal,就可能 ...

  9. 并发编程(四):ThreadLocal从源码分析总结到内存泄漏

    一.目录      1.ThreadLocal是什么?有什么用?      2.ThreadLocal源码简要总结?      3.ThreadLocal为什么会导致内存泄漏? 二.ThreadLoc ...

随机推荐

  1. PID控制動手玩玩看

    PID控制動手玩玩看 PID三個參數到底該怎麼調才好,真的是一門藝術. 雖然在Marlin韌體內有提供自動測量的功能,但是測得的結果,不見得能令人滿意,還是需要調整.可是到底該怎麼調整?從哪個參數開始 ...

  2. aic bic mdl

    https://blog.csdn.net/xianlingmao/article/details/7891277 https://blog.csdn.net/lfdanding/article/de ...

  3. 【2017-02-28】C# 冒泡排序

    冒泡排序 重复地走访过要排序的数列,一次比较两个元素的大小,如果他们的顺序错误就把他们交换过来 通过两个For循环嵌套来实现 思路——以从小到大为例 第一个for循环抽取第一个数和第二个数进行比较,如 ...

  4. Xfire基础

    XFire 是与Axis 2并列的新一代Web Service框架,通过提供简单的API支持Web Service各项标准协议,能够快速地开发Web Service应用.和其他Web服务引擎相比,XF ...

  5. SpringMVC七种参数绑定简单介绍

    a. 默认支持的类型:        httpServletRequest, httpservletresponse, httpsession, model        看自己需要, 如果需要用就加 ...

  6. px-pt-dp-rem像素单位的换算问题

    px-pt-dp-rem像素单位的换算问题 dp 的意思从 MDPI 到 XXXHDPI 每单位物理尺寸的像素数越来越大.也就是说 mdpi 时 1dp = 1pxxxxhdpi 时 1dp = 4p ...

  7. js多个异步请求

    一,两个(或多个)js异步并发执行,怎么在两个AJax异步操作之后执行一个新的操作 原题来自 ES6 方法 1.Promise 包装异步ajax操作,2.定义async 函数,3.用await等待pr ...

  8. [转载]CSS教程--字体与文本属性

    b>font-family功能:用于改变HTML标志或元素的字体,你可设置一个可用字体清单.浏览器由前向后选用字体.语法:{font-family:字体1,字体2, ... ,字体n} font ...

  9. yield的理解

    yield的理解:yield命令是异步两个阶段的分界线需要先对迭代器和生成器进行理解: 迭代器:是一种支持next()操作的对象.它包含一组元素,当执行next()时,返回其中一个元素:当所有元素都被 ...

  10. C++中虚函数的作用

    一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你就应该从这里开始) 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Po ...