【Java】ThreadLocal细节分析
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细节分析的更多相关文章
- Java ThreadLocal 源代码分析
Java ThreadLocal 之前在写SSM项目的时候使用过一个叫PageHelper的插件 可以自动完成分页而不用手动写SQL limit 用起来大概是这样的 最开始的时候觉得很困惑,因为直接使 ...
- java基础解析系列(七)---ThreadLocal原理分析
java基础解析系列(七)---ThreadLocal原理分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)-- ...
- Java文件读写分析
本文内容:IO流操作文件的细节分析:分析各种操作文件的方式. 读写一个文件 从一个示例开始分析,如何操作文件: /** * 向一个文件中写入数据 * @throws IOException */ pr ...
- 常用 Java 静态代码分析工具的分析与比较
常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...
- Java线程问题分析定位
Java线程问题分析定位 分析步骤: 1.使用top命令查看系统资源占用情况,发现Java进程占用大量CPU资源,PID为11572: 2.显示进程详细列表命令:ps -mp 11572 -o THR ...
- Java提高篇(三五)-----Java集合细节(一):请为集合指定初始容量
集合是我们在Java编程中使用非常广泛的,它就像大海,海纳百川,像万能容器,盛装万物,而且这个大海,万能容器还可以无限变大(如果条件允许).当这个海.容器的量变得非常大的时候,它的初始容量就会显得很重 ...
- java内存溢出分析(二)
我们继续java内存溢出分析(一)的分析,点击Details>按钮,显示如下图,我们发现有一个对象数量达到280370216个,再点击其中的List objects 点击后,显示下图 至此,我们 ...
- 性能分析之-- JAVA Thread Dump 分析综述
性能分析之-- JAVA Thread Dump 分析综述 一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工 ...
- java初学的分析
java初学的分析第一阶段:入门阶段学习目标:简单项目开发学习内容:1.Java入门书籍,Java基础知识.关于Java入门级的书,给大家推荐过<Java编程思想>.<Java核心技 ...
随机推荐
- 2. Abstract Factory(抽象工厂)
意图: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性: 一个系统要独立于它的产品的创建.组合和表示时. 一个系统要由多个产品系列中的一个来配置时. 当你要强调一系列相关 ...
- Markdown 基本入门使用
http://www.appinn.com/markdown/ markdown快速入门Markdown 常用语法: # 标题 强调:用星号(*)和底线(_)作为标记强调字词的符号,如果你的 * 和 ...
- spring aop实现
Spring 有如下两种选择来定义切入点和增强处理. 基于 Annotation 的"零配置"方式:使用@Aspect.@Pointcut等 Annotation 来标注切入点和增 ...
- 第三次作业——《K米评测》
第三次作业--<K米评测> 一.调研.评测 上手体验 APP的图标做的不错,一眼就知道和KTV唱歌相关的 点进去就是连接包箱的界面和直播界面,把软件最重要的两个功能展示出来了,一目了然 热 ...
- eclipse中java项目的build path详解
BuildPath中只支持加入jar文件,具体方法如下:在eclips里在工程名上右键->build path->contigure bud path->java build pat ...
- runtime 运行机制
// // HKPerson.h // runtimeDemo1 // // Created by 123 on 16/5/23. // Copyright © 2016年 123. All ...
- 使用 KGDB 调试 Kernel On Red Hat Linux
1. KGDB 简介 KGDB 提供了一种使用 GDB 调试 Linux 内核的机制.使用 KGDB 可以象调试普通的应用程序那样,在内核中进行设置断点.检查变量值.单步跟踪程序运行 ...
- Java使用Scanner接收中文并输出时出现乱码
Java中使用Scanner接收输入的中文并输出时会出现乱码现象,怎么解决此问题呢? 1.方法一 在声明Scanner时添加对应的编码格式就可以了,如下所示: Scanner sc = new Sca ...
- hdoj 1272 小希的迷宫
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了 ...
- 使用nginx为ArcGIS Server做反向代理
1.下载nginx软件:官网地址http://nginx.org/ 2.修改conf文件夹下nginx.conf配置信息, 配置文件中以下内容: server { listen 80; s ...