26 | 答疑课堂:模块四热点问题解答
该思维导图由 AI 生成,仅供参考
第 20 讲
第 21 讲
第 22 讲
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了JVM性能监测及调优的关键问题,涵盖了JVM内存模型、元空间、Hotspot虚拟机、CMS和G1垃圾收集器等内容。文章详细介绍了垃圾收集器的特点、区别以及相关参数设置,同时解答了读者提出的关于ThreadLocal、内存泄漏和内存溢出的问题。作者鼓励读者提问,并表示愿意解答任何疑问。整体来看,本文对于想要深入了解JVM性能优化的读者具有一定的参考价值。
《Java 性能调优实战》,新⼈⾸单¥59
全部留言(16)
- 最新
- 精选
- Nu11PointerEx刘老师,我有个疑问,文中指出弱引用只能存活再下次GC之前,那假如线程在步骤A设置了threadlocal的值,然后需要在步骤B读出来,但是在AB之间发生了GC,这样会不会导致在步骤B中无法取到对应的值
作者回复: 如果线程没有销毁,也就是说该key值依然存在引用,即使是弱引用,也不会被回收掉。
2019-07-3148 - -W.LI-老师好!最近正好在看多线程编程指南。有个东西没搞明白。 我自己写了个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队列中,再尝试获取锁。
2019-07-205 - Stalary老师,ThreadLocal使用的时候我存储了一些请求相关的东西,没有使用remove,但是一次请求结束就会自动释放掉了吧,是不是不会出现内存泄漏?还是没太明白出现内存泄漏的场景,线程不都是工作完就会释放掉了吗
作者回复: 是的,如果我们的线程在使用ThreadLocal的set之后就立刻销毁了,此时之前set的线程的key值通过垃圾回收回收掉,此时value则会存在内存泄漏,而马上又有下一个线程使用ThreadLocal的set,则会清除之前key为null的value,这种情况下是不会出现内存泄漏的。 也就是ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。 我们可以使用set之后,sleep下该线程,等待其他请求都一起使用完了set,这样很容易重现内存中的一部分对象无法回收掉。
2019-07-2854 - nightmare老师cms和g1能不能加餐讲详细一点 因为互联网公司 cms和g1问的非常多
作者回复: 好的,可以考虑。
2019-07-203 - 风轻扬老师,jdk1.6的substring导致内存泄漏的问题。大字符串截取完之后,我们直接把原大字符串的引用置为null,可以解决这个内存泄漏的问题吗?
作者回复: 不行,只是原来的引用置为null了,但堆中的字符串对象依然不会被回收掉
2019-09-112 - Mq老师threadlocal的entry不回收是因为value吗,另外我不理解jvm怎么知道我这次gc的时候key就可以回收,会不会出现我多次get的时候有一次就取不到了
作者回复: 如果线程还存活,此时get是能获取到的,因为还存在强引用。如果线程生命周期已经结束,则ThreadLocal的线程本地变量将会失去引用,我们知道ThreadLocal是成员变量,如果key值没有设置为弱引用,则结束生命周期的线程变量依然会存在ThreadLocal中。 所以,当线程生命周期结束,ThreadLocal的key又为了弱引用,key值就会在垃圾回收期被回收掉。
2019-07-222 - ヾ(◍°∇°◍)ノ゙java的垃圾回收使用的是复制算法和标记整理算法,这样对象的内存是变化的吧?那么引用它的栈上的地址也会变掉吗?如果是的话如果hashmap的key如果没有自己实现hashcode的话,是不是就会引起了内存泄漏和程序错乱
作者回复: 是的,对象的引用也被指向新的地址。
2019-07-222 - 钱我们的项目中ThreadLocal使用的蛮多的,使用原因是因为接口调用链长不想修改方法生命,但有些参数要透传就用ThreadLocal来透传参数。 老师能否介绍一下题ThreadLocal的最佳实践?什么场景下会使用?有什么坑需要填?怎么规避风险?
作者回复: 我们可以读取大部分读写中间件实现源码,可以发现ThreadLocal使用的最为频繁,通常是通过ThreadLocal来获取当前线程的操作类型来实现读写数据源的切换。 在使用完之后实现remove操作,可以规避风险。
2019-09-1231 - 风轻扬老师,jdk1.6的substring的内存泄漏问题。除了升级jdk版本,您有没有其他的办法。我在网上搜了一下,没有看到啥好办法
作者回复: 升级版本就好了,现在基本都是基于1.8版本了
2019-09-1121 - 尔冬橙这是一门神课2019-09-0233