Comments (6)
我在#521这个ISSUE中找到了想要的答案, @oldratlee 感谢
from transmittable-thread-local.
非常感谢 @oldratlee 的回答,今天花了一天时间研究这一块,其实值传递的核心是
- capture【获取父线程中的值,包括引用对象或普通对象】
- replay【回放:备份、将父线程的值设置到子线程】
- restore【会将子线程执行之前backup的值设置回子线程的ThreadLocal】;
如果通过如下关闭Interitable能力:
@Override
protected User childValue(User parentValue) {
return initialValue();
}
那么在子线程replay回放时backup就不存在,所有在restore恢复的时候子线程其实是不存在值恢复的;
如果不关闭Interitable能力,那么子线程继承了父线程的值【普通对象、引用类型】,在restore后会将子线程的值恢复成从父线程继承的值或引用类型,但是如果子线程执行结束了,那么子线程的ThreadLocal就不会持有父线程的上下文了,这是因为ThreadLocal的生命周期是和线程的生命周期相关联,线程结束,则ThreadLocal变量也会自动被GC销毁;
还有个问题,就是线程池复用的问题,如果不关闭线程的Interitable能力,则子线程继承父线程的引用对象,如果执行完成后被线程池复用,那么就会有一部分引用对象一直无法释放,如果这个量比较大的话有可能造成OOM,像这种问题又是如何解决的呢?
有空了帮忙解答下,谢谢!
from transmittable-thread-local.
TransmittableThreadLocal内部本身定义了holder变量如下:
private static final InheritableThreadLocal<WeakHashMap<TransmittableThreadLocal<Object>, ?>> holder =
new InheritableThreadLocal<WeakHashMap<TransmittableThreadLocal<Object>, ?>>() {
@Override
protected WeakHashMap<TransmittableThreadLocal<Object>, ?> initialValue() {
return new WeakHashMap<>();
}
@Override
protected WeakHashMap<TransmittableThreadLocal<Object>, ?> childValue(WeakHashMap<TransmittableThreadLocal<Object>, ?> parentValue) {
return new WeakHashMap<TransmittableThreadLocal<Object>, Object>(parentValue);
}
};
其中InheritableThreadLocal内部存储的是一个WeakHashMap类型,其键是一个WeakReference类型,如果没有强引用的话就会在下次GC的时候回收掉,而其value本身就是null,所以对于TTL本身来说是不存在内存溢出问题的;
对于子线程而言其值是存在于Thread线程的ThreadLocal.ThreadLocalMap inheritableThreadLocals变量中,而ThreadLocalMap内部的存储结构是一个WeakReference类型,如果没有强引用则会在下次GC的时候置为null,在下次使用的时候会主动清除掉key为null引用,从而避免OOM;
上述异步线程池中最外层主线程主动remove,内部无法主动remove,而不会造成OOM的原因是不是上述分析的 @oldratlee 帮忙解答下,谢谢
from transmittable-thread-local.
因为有「恢复(Transmitter.restore()
)」操作做了清除操作,
在运行完任务之后子线程(的ThreadLocal
)不再持有上下文,
所以不会因为这个传递过程而引入内存泄露。 @mingyang66
注意:上面的过程 不包含「由Inheritable
能力(InheritableThreadLocal
) 带给子线程的上下文」这个情况。
对于Inheritable
能力引起的「内存泄露」,有较多讨论,
可以看看网上的讨论、或这个库涉及「内存泄露」相关的issue。
TTL
提供了关闭Inheritable
的一些方法,具体参见TransmitableThreadLocal
的JavaDoc。
from transmittable-thread-local.
我看很多案例和issue中都没有调用TransmittableThreadLocal.remove方法移除上下文的操作,是不是因为TTL中使用WeakHashMap和ThreadLocal使用WeakRefrence的原因?GC的时候会自动回收?
from transmittable-thread-local.
我看很多案例和issue中都没有调用TransmittableThreadLocal.remove方法移除上下文的操作,是不是因为TTL中使用WeakHashMap和ThreadLocal使用WeakRefrence的原因?GC的时候会自动回收?
@mingyang66 上一条评论有原因的一些解释:
因为有「恢复(
Transmitter.restore()
)」操作做了清除操作,
在运行完任务之后子线程(的ThreadLocal
)不再持有上下文,
所以不会因为这个传递过程而引入内存泄露。 @mingyang66
注意:上面的过程 不包含「由Inheritable
能力(InheritableThreadLocal
) 带给子线程的上下文」这个情况。
如果想更多深入理解说明TTL
的实现设计,
- 可能直接看源码研究实现逻辑、并运行调试验证 是一个比较有效的方法。 @mingyang66
- (我的语言解释起来 并不简单直观
😬 )
- (我的语言解释起来 并不简单直观
- 当然
TTL
有不少介绍与解析的文章(解释得比我好💕 ):
from transmittable-thread-local.
Related Issues (20)
- 复现TransmittableThreadLocal数据在「不用TtlExecutors包裹的线程池」中概率丢失。 HOT 1
- TTL是否适用于tomcat的StandardThreadExecutor,尝试了agent的方式和显式包装的方式都不行 HOT 1
- 线程池每次执行完成后默认将上下文还原至调用线程的上下文原状,可以执行完成后将线程中的上下文全部清除掉吗 HOT 1
- 集成`Spring Reactor` HOT 1
- jdk11 报错。 HOT 4
- ttl是否不支持rocketMQ的上下文传递 HOT 1
- 在CompletableFuture中使用TTL,主线程执行完成,但CompletableFuture未完成,是否可以可以释放上下文,主线程释放上下文后,CompletableFuture是否还能拿到TTL的值 HOT 1
- 加入agent后报TtlTransformer: Fail to transform class xxx 错误 HOT 4
- agent中对普通Thread场景进行包装,来触发copy方法 HOT 2
- agent方式使用TTL,jdk从8升到11之后项目启动报错 类重复加载: java.lang.LinkageError: loader java.net.URLClassLoader attempted duplicate class HOT 3
- “业务项目”在通过bytebuddy增强后,TTL+CompletableFuture无法再正常地进行上下文传递。 HOT 1
- 关于不修饰runnable使用ttl导致子线程泄露问题 HOT 3
- -
- 与其他探针放在一起使用的时候,如果ttlagent顺序在其他探针之后,探针失效无法跨线程 HOT 7
- 关于registerThreadLocal方法加锁和copy on write疑问 HOT 1
- 有必要关闭Inheritable能力么 HOT 5
- TTL使用完成后需要remove掉当前线程的值吗?如果不删除会不会引发OOM? HOT 3
- 如何在ttl里面使用BinaryOperator HOT 1
- 使用Java agent不生效,通过arthas jad看对应的类,均已被transform,但是trace不到TtlRunnable和TransmittableThreadLocal的执行记录 HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from transmittable-thread-local.