ThreadLocal通过中文解释就是线程本地变量,是线程的一个局部变量。根据哲学家黑格尔“的存在即合理”的说法,ThreadLocal的出现肯定是有它的意义,它的出现也是因为多线程的一个产物。ThreadLocal既然跟线程有关系,那肯定得先对线程了解了解。

从网上找来了一句话:Java线程的创建,除了堆栈空间,每个线程还需要为线程本地存储(thread-local storage)和内部数据结构提供一些本机内存。

先来学习一下什么是堆栈空间

以上是Java虚拟机运行时数据区的结构图,从图中看出,堆栈(即图中的虚拟机栈)是Java运行时内存分配的一部分,这个堆栈的大小可以用过JVM启动参数Xss设置(JDK5+版本默认好像是1M),那么,这个堆栈是干什么用的呢?大学期间有认真学习过一些技术课程如操作系统、数据结构、C语言等学科的话,不在话下。可惜,我不是这种学生。为了能理解堆栈的一些相关知识,我快速阅览相关知识继续学习(现在才知道大学的知识真的是很用,如果再给我4年时间,算了,现在学习也为时不晚)。一句话,它是线程执行方法(字节码)的地方,每创建一个线程实例,就是分配固定大小(Xss设置参数)的内存空间给线程执行方法用,具体结构图如下:

上图的每一个栈帧就相当于一个方法的执行,更多可参考《深入理解Java虚拟机》8.2章节。

上面已经大概的了解了一下堆栈,那就再来看看线程的堆栈与本地变量的一个关系结构图:

我们知道,线程实例也是一个对象,对象都是存放在堆里面的。从上图可以看出,当创建一个新的线程,那么就会有一个相对应的堆栈空间创建,那个stack部分就可以很好的解析上文提到的一句话“Java线程的创建,除了堆栈空间,每个线程还需要为线程本地存储(thread-local storage)和内部数据结构提供一些本机内存”。这个stack区域就是堆栈空间,而在这个堆栈空间里面有两个直线了堆栈对象的引用,一个是线程实例的应用,另一个就是本地变量的引用。

总结:

1、  堆栈的溢出不会直接因为ThreadLocal保存对象的过大的导致堆栈溢出,因为线程堆栈保存的只是引用。真正的对象还是在堆里面,如果对象大到超出堆内存的限制,反而会导致堆溢出。

2、  从源码可以看出,每个Thread中都存在一个Map,Map的类型是ThreadLocal.ThreadLocalMap。Map中的key为一个Threadlocal实例。这个Map的确使用了弱引用,不过弱引用只是针对key。每个key都弱引用指向Threadlocal。 当把Threadlocal实例置为null以后,没有任何强引用指向Threadlocal实例,所以Threadlocal将会被gc回收。但是,我们的value却不能回收,因为存在一条从current thread连接过来的强引用。只有当前thread结束以后, current thread就不会存在栈中,强引用断开,Current Thread、 Map,、value将全部被GC回收。

3、  堆栈的生命周期是跟随着线程的生命周期,当线程池中的线程实例还在,堆栈也不会被回收或者清空,所以,原来的ThreadLocalMap还是存在的。所以,当线程池与ThreadLocal同时使用的时候特别需要注意。

【Java】ThreadLocal细节分析的更多相关文章

  1. Java ThreadLocal 源代码分析

    Java ThreadLocal 之前在写SSM项目的时候使用过一个叫PageHelper的插件 可以自动完成分页而不用手动写SQL limit 用起来大概是这样的 最开始的时候觉得很困惑,因为直接使 ...

  2. java基础解析系列(七)---ThreadLocal原理分析

    java基础解析系列(七)---ThreadLocal原理分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)-- ...

  3. Java文件读写分析

    本文内容:IO流操作文件的细节分析:分析各种操作文件的方式. 读写一个文件 从一个示例开始分析,如何操作文件: /** * 向一个文件中写入数据 * @throws IOException */ pr ...

  4. 常用 Java 静态代码分析工具的分析与比较

    常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...

  5. Java线程问题分析定位

    Java线程问题分析定位 分析步骤: 1.使用top命令查看系统资源占用情况,发现Java进程占用大量CPU资源,PID为11572: 2.显示进程详细列表命令:ps -mp 11572 -o THR ...

  6. Java提高篇(三五)-----Java集合细节(一):请为集合指定初始容量

    集合是我们在Java编程中使用非常广泛的,它就像大海,海纳百川,像万能容器,盛装万物,而且这个大海,万能容器还可以无限变大(如果条件允许).当这个海.容器的量变得非常大的时候,它的初始容量就会显得很重 ...

  7. java内存溢出分析(二)

    我们继续java内存溢出分析(一)的分析,点击Details>按钮,显示如下图,我们发现有一个对象数量达到280370216个,再点击其中的List objects 点击后,显示下图 至此,我们 ...

  8. 性能分析之-- JAVA Thread Dump 分析综述

    性能分析之-- JAVA Thread Dump 分析综述       一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工 ...

  9. java初学的分析

    java初学的分析第一阶段:入门阶段学习目标:简单项目开发学习内容:1.Java入门书籍,Java基础知识.关于Java入门级的书,给大家推荐过<Java编程思想>.<Java核心技 ...

随机推荐

  1. IIS 的一些配置记录

    1.日志分析: URL:http://www.cnblogs.com/fish-li/p/3139366.html2.性能监视: 执行 perfmon.msc ,右键添加counter,添加web s ...

  2. 《笨办法学C》笔记之Makefile

    使用gcc编译C语言源码 在Linux系统中,C语言源码需要用gcc编译为二进制可执行文件,才能够运行. $ gcc test.c -o test 这句命令就将test.c文件编译为test二进制可执 ...

  3. maven 三个基本插件 clean dependency compiler

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  4. silverLight--绑定数据dataGrid

    后台代码编写 ,为表格绑定数据: using System; using System.Collections.Generic; using System.Linq; using System.Net ...

  5. js高阶函数

    我是一个对js还不是很精通的选手: 关于高阶函数详细的解释 一个高阶函数需要满足的条件(任选其一即可) 1:函数可以作为参数被传递 2:函数可以作为返回值输出 吧函数作为参数传递,这代表我们可以抽离一 ...

  6. 发现的eval的一个小问题

    首先我们来看五段代码: 第一段代码: function test(){ eval('var a = 1;'); alert(a); } test(); 第二段代码: function test(){ ...

  7. 编译gtk+程序报错gcc: pkg-config --cflags --libs gtk+-2.0: 没有那个文件或目录

    第一次接触gtk+.在网上搜罗良一番,装好相应的库后,编写了第一hello程序.在编译时输入以下命令:gcc -o hello hello.c 'pkg-config --cflags --libs ...

  8. Popup - 弹出层

    //图片类快捷弹出层 <a href="" target="_blank"> <div class="panlifang1" ...

  9. IAR之文件路径设置

    1.命令解释 $PROJ_DIR$表示工程所在路径 $TOOLKIT_DIR$表示IAR安装目录所在头文件路径 \..\表示返回上一级目录. 2.头文件路径设置 打开工程文件,找到"opti ...

  10. myBatis+SpringMVC+Maven整合

    一.先创建表结构 二.使用generator通过表结构自动生成model和dao.mapper 使用步骤: 1.解压generator.rar文件 2.文件中的generator.xml文件需要进行修 ...