首页 > 系统相关 >ThreadLocal发生内存泄漏的真正原因——豁然开朗

ThreadLocal发生内存泄漏的真正原因——豁然开朗

时间:2024-03-31 17:31:53浏览次数:18  
标签:Thread remove value ThreadLocal 线程 内存 key 豁然开朗

很久很久以前的以前,对于这个问题,网上众说纷纭:key为弱引用,会被下一次gc回收,value强引用,会造成value永远不会回收,然后OOM。

???似懂非懂?懂不了一点?

搞懂就在一瞬间

源码搞起

1、ThreadLocal里面维护了一个ThreadLocalMap。

2、当我们使用ThreadLocal设置值的时候


    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

看重点-------->这个ThreadLocalMap中存放的key是当前线程Thread.currentThread(),当前线程,当前线程,重要的事情说三遍

那也就是说所有使用了ThreadLocal来存放数据的线程共用一个Map,而他们的线程安全是由Map的key不能重复保证的,这时候如果key被回收了,key为null会发生什么?如果再set呢?

回到开头,有没有一瞬间豁然开朗的感觉?

所以,ThreadLocal内存泄漏的真正原因,key被回收,key为null,value一直存在,当线程再来set的时候,就会新加一对新的key和value,如此往复,这个Map总有一天会大到离谱,OOM是必须的了。

ThreadLocal中也提供了remove方法,所以在使用完ThreadLocal的时候记得显示调用下remove方法

     public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

标签:Thread,remove,value,ThreadLocal,线程,内存,key,豁然开朗
From: https://blog.csdn.net/weixin_45967584/article/details/137204111

相关文章

  • C++原子操作与内存序 1
    问题#include<iostream>#include<thread>intmain(){ intsum=0; autof=[&sum](){ for(inti=0;i<10000;i++) sum+=1; }; std::threadt1(f); std::threadt2(f); t1.join(); t2.join(); std::cout<<"thesum......
  • Linux——共享内存
    Linux——共享内存什么是共享内存共享内存原理Linux下共享内存的接口创建/获取共享内存:shmgetftok函数映射共享内存到进程地址空间:shmat解除共享内存映射:shmdt删除共享内存段:shmctl利用共享内存进行通信我们之前学习了匿名管道,命名管道来进行进程之间的通信,其实除......
  • 【C++】内存管理
    在学习完类与对象后,在学习C++中,接下来需要学习的是内存管理,在本篇博客中将会讲解C++的内存管理。 一.C/C++内存分布在学习内存管理前,我们先来了解一下C/C++的内存分布。 一般来说,内存可以分为四个区域:栈区、堆区、数据段、代码段。栈区:用于存放非静态的局部变量,函......
  • linux物理内存,虚拟内存的获取
    使用文件流的方式,解析   cat/proc/meminfo 文件里面的数据 #include<iostream>#include<fstream>#include<sstream>#include<string>#include<unordered_map>#include<map>structBASE_INFO_S{unsignedlonglongMemTot......
  • 数据在内存中的储存详解
    我们在使用某一个变量时有没有想过这个变量在内存中是如何储存的呢?是我们输入一个十进制的值,内存中就直接储存这个十进制的值,还是别的内容呢?1.整数在内存中的存储我们首先说结论,那就是整数在内存中是以一个二进制补码的方式来存储的。我们以整形int为例,一个整形是4个字节,一......
  • 嵌入式中内存分配-栈区、堆区、全局区、常量区和代码区详解
    一、C语言内存分区C语言内存分区示意图如下:1.栈区栈区介绍栈区由编译器自动分配释放,由操作系统自动管理,无须手动管理。栈区上的内容只在函数范围内存在,当函数运行结束,这些内容也会自动被销毁。栈区按内存地址由高到低方向生长,其最大大小由编译时确定,速度快,但自......
  • 《C++ Primer 第五版 中文版》第12章 动态内存【阅读笔记 + 个人思考】
    《C++Primer第五版中文版》第12章动态内存【阅读笔记+个人思考】12.1动态内存与智能指针12.1.1shared_ptr类静态内存包括:初始化只读数据段,初始化读写数据段,未初始化数据和常量数据段。详细在下面博客总结:Linux系统下C++程序运行时的内存布局及存储内容,生......
  • 【C语言基础】:数据在内存中的存储
    文章目录一、整数在内存中的存储二、大小端字节序和字节序判断1.为什么有大小端?2.练习三、浮点数在内存中的存储1.浮点数的存储1.1浮点数的存储过程1.2浮点数取的过程四、题目解析     书山有路勤为径,学海无涯苦作舟。创作不易,宝子们!如果这篇文......
  • 在Linux中,什么是虚拟内存?它是如何工作的?
    虚拟内存是一种内存管理技术,它允许操作系统使用硬盘空间来模拟额外的内存资源。虚拟内存的工作原理涉及以下几个关键概念:地址空间:每个进程拥有自己的虚拟地址空间,这个空间对于进程来说是一致的和私有的。虚拟地址空间的大小通常远大于物理内存的大小。分页机制:操作系统将物理......
  • 直播平台制作,优化内存占用不妨试试轻量级数据架构
    直播平台制作,优化内存占用不妨试试轻量级数据架构使用轻量级数据结构在直播平台制作中选择数据结构时,考虑使用轻量级的数据结构,如ArrayList替代Vector,以及StringBuilder替代String拼接。能够在保证功能的前提下,减小内存占用。以下是一些使用轻量级数据结构的方法:1、使用......