栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

ThreadLocal使用与如何避免内存泄漏

Java 更新时间:发布时间: 百科书网 趣学号
ThreadLocalMap数据结构

  与其他map相类似,ThreadLocalMap内部存储的数个格式也是形式的。不同点在于,ThreadLocalMap的key设置的当前线程,value设置的是继承自弱引用类型的WeakReference的Entry对象。

  通过阅读源码,不难发现。ThreaLocalMap在使用的时候。其实都是在方法内部,获取到了本地线程,进行操作的。


  ThreadLocalMap整体的数据结构可以理解为一个只能存放单个key对象的map集合。

ThreadLocal使用场景

ThreadLocal的使用场景,其实比较容易。首先得知道ThreadLocal得特性才行。
特性比如:

  • 线程私有,不可共享
  • 只能存放单个值对象
    所以总体而言,一般这个容器,可以用来存放仅供当前线程使用,但又不方便(或者没必要)进行重复值传递得对象。
    比如说:
  • 已有得系统上,需要接入多租户信息,为了达到数据操作时,有数据级别的隔离。这时候,我们要么在原有系统上,进行大刀阔斧得,每个查询、新增、修改方法都需要加上租户。不如直接使用spring得aop特性。在接口得初始化调用时,存放到统一得map中,在sql查询时拦截sql进行拼接。
ThreadLocal产生内存泄漏的原因

首先内存泄漏是什么东西呢?
  内存泄漏是程序在申请内存后,无法释放已申请的内存空间,多次内存泄漏就会导致内存耗光的严重问题。
  在这里就有个概念了,在Java中存在多种应用对象。
  强引用:使用最普遍的引用(new),一个对象具有强引用,不会被垃圾回收器回收。当内存空间不足,java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不回收这种对象。
  如果想取消强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样可以使JVM在合适的时间回收该对象。

  弱引用:JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。可以在缓存中使用弱引用。

  我们的ThreadLocal存放得entry就是被WeakReference标记得弱引用类型对象。

  ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal不存在外部强引用时,key(ThreadLocal)就会被GC回收,这样就会导致ThreadLocalMap中key为null,而value还存在强引用,只用thread线程退出,value的强引用链条才会断掉,但如果当前线程未结束,这些key为null的Entry的value就会一直存。
  如果ThreadLocalMap的key为强引用回收ThreadLocal时,因为ThreadLocalMap还持有ThreadLocal的强引用,如果没有手动删除,ThreadLocal就不会被回收,导致Entry内存泄漏。

  ThreadLocalMap的key为弱引用回收ThreadLocal时,由于ThreadLocalMap持有ThreadLocal的弱引用,即使没有手动删除,ThreadLocal也会被回收。当key为null,在下一次ThreadLocalMap调用set(),get(),remove()时会清除value的值。

  因此,ThreadLocal内存泄漏的根源是由于ThreadLocalMap的生命周期和Thread一样长,如果没有手动删除对应key就会导致内存泄漏,而不因为弱引用。

如何避免ThreadLocal产生的内存泄漏

ThreadLocal正确的使用方法:

  1. 每次使用完ThreadLocal都要调用它的remove()清除数据。
  2. 将ThreadLocal变量定义成private static,这样就一直存在ThreadLocal的强引用,也能保证任何时候都能通过ThreadLocal的弱引用访问到Entry的value值,进而清除掉。
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/956838.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号