26 | 答疑课堂:模块四热点问题解答
26 | 答疑课堂:模块四热点问题解答
讲述:李良
时长12:12大小11.17M
第 20 讲
第 21 讲
第 22 讲
第 23 讲
第 24 讲
赞 8
提建议
精选留言(16)
- 尔冬橙2019-09-02这是一门神课33
- Nu11PointerEx2019-07-31刘老师,我有个疑问,文中指出弱引用只能存活再下次GC之前,那假如线程在步骤A设置了threadlocal的值,然后需要在步骤B读出来,但是在AB之间发生了GC,这样会不会导致在步骤B中无法取到对应的值
作者回复: 如果线程没有销毁,也就是说该key值依然存在引用,即使是弱引用,也不会被回收掉。
共 4 条评论7 - -W.LI-2019-07-20老师好!最近正好在看多线程编程指南。有个东西没搞明白。 我自己写了个demo把所有线程都在临界区调用wait方法,wait方法后是sleep方法。我在主线程调用了notifyall(),在临界区内打印了所有线程的状态,notifyall()之前都是waiting,之后都是blocked。出了临界区之后又打印了一次,发现有一个是timed_waiting,别的还是blocked。 从表现来看 notifyall():wait->blocked 调用notifyall()的线程出临界区释放锁锁: 竞争到锁定blocked->runnable,别的还是blocked。 之前老师说notifyall()在出临界区的时候调用比较好,可以防止被唤醒的阻塞状态线程,竞争不到锁再次阻塞。 notifyall是本地方法看不到实现。我想确认下 notifyall的逻辑是:唤醒waiting线程->尝试获取锁->获取不到blocked? 还是:所有waiting状态线程->blocked状态进去锁池队列。(只有在有线程释放锁的时候(出临界区)才会从锁池队列拿一个线程尝试获取锁)。我比较倾向于第二种。没看源码希望老师帮忙解惑下,我特意翻了之前的课在那边也留言了,老师在这回复就好了谢谢老师展开
作者回复: 对的,调用wait之后,会进入到WaitSet队列,当调用notify之后,默认策略是将其从WaitSet队列转至EntryList队列中,再尝试获取锁。
5 - Stalary2019-07-28老师,ThreadLocal使用的时候我存储了一些请求相关的东西,没有使用remove,但是一次请求结束就会自动释放掉了吧,是不是不会出现内存泄漏?还是没太明白出现内存泄漏的场景,线程不都是工作完就会释放掉了吗
作者回复: 是的,如果我们的线程在使用ThreadLocal的set之后就立刻销毁了,此时之前set的线程的key值通过垃圾回收回收掉,此时value则会存在内存泄漏,而马上又有下一个线程使用ThreadLocal的set,则会清除之前key为null的value,这种情况下是不会出现内存泄漏的。 也就是ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。 我们可以使用set之后,sleep下该线程,等待其他请求都一起使用完了set,这样很容易重现内存中的一部分对象无法回收掉。
共 3 条评论4 - nightmare2019-07-20老师cms和g1能不能加餐讲详细一点 因为互联网公司 cms和g1问的非常多
作者回复: 好的,可以考虑。
3 - 风轻扬2019-09-11老师,jdk1.6的substring导致内存泄漏的问题。大字符串截取完之后,我们直接把原大字符串的引用置为null,可以解决这个内存泄漏的问题吗?
作者回复: 不行,只是原来的引用置为null了,但堆中的字符串对象依然不会被回收掉
2 - ヾ(◍°∇°◍)ノ゙2019-07-22java的垃圾回收使用的是复制算法和标记整理算法,这样对象的内存是变化的吧?那么引用它的栈上的地址也会变掉吗?如果是的话如果hashmap的key如果没有自己实现hashcode的话,是不是就会引起了内存泄漏和程序错乱
作者回复: 是的,对象的引用也被指向新的地址。
2 - Jxin2019-07-20抛砖引玉了,感谢老师的知无不尽。( ´◔‸◔`)2
- 钱2019-09-12我们的项目中ThreadLocal使用的蛮多的,使用原因是因为接口调用链长不想修改方法生命,但有些参数要透传就用ThreadLocal来透传参数。 老师能否介绍一下题ThreadLocal的最佳实践?什么场景下会使用?有什么坑需要填?怎么规避风险?
作者回复: 我们可以读取大部分读写中间件实现源码,可以发现ThreadLocal使用的最为频繁,通常是通过ThreadLocal来获取当前线程的操作类型来实现读写数据源的切换。 在使用完之后实现remove操作,可以规避风险。
共 3 条评论1 - 风轻扬2019-09-11老师,jdk1.6的substring的内存泄漏问题。除了升级jdk版本,您有没有其他的办法。我在网上搜了一下,没有看到啥好办法
作者回复: 升级版本就好了,现在基本都是基于1.8版本了
共 2 条评论1 - Mq2019-07-22老师threadlocal的entry不回收是因为value吗,另外我不理解jvm怎么知道我这次gc的时候key就可以回收,会不会出现我多次get的时候有一次就取不到了
作者回复: 如果线程还存活,此时get是能获取到的,因为还存在强引用。如果线程生命周期已经结束,则ThreadLocal的线程本地变量将会失去引用,我们知道ThreadLocal是成员变量,如果key值没有设置为弱引用,则结束生命周期的线程变量依然会存在ThreadLocal中。 所以,当线程生命周期结束,ThreadLocal的key又为了弱引用,key值就会在垃圾回收期被回收掉。
2 - 明翼2019-07-22超哥,有问题请教下: 1)曾经被问到一个问题,就是java多线程分配内存的时候是如何控制并发冲突的那? 2)能不能结合代码把java内存创建的过程讲一次,比如成员变量的引用是在哪里分配的(我理解是堆上),堆上还是栈上,临时变量那,通过这种整体的讲解会对我们印象比较深刻。共 2 条评论1
- ty_young2020-05-02老师您好,card table只是老年代才维护的吧,那G1垃圾收集器的RSet也是只维护老年代的引用么(老年代引用年轻代和老年代引用老年代)共 1 条评论
- ty_young2020-04-29求老师把cms,g1讲得详细点,求加餐
- asura2020-01-24每次看完课程,课后评论也会看完。大家看问题的角度不同,思考纬度也不同,着实学到了很多 👍。感谢老师的热情回答!
- ty_young2019-10-27真的受益颇多,谢谢老师