关于 JVM Class被回收卸载的问题?-灵析社区

爱打瞌睡的三角龙

问题的背景是我看到了这篇文章: [https://zhuanlan.zhihu.com/p/146410261](https://link.segmentfault.com/?enc=RyvEA0WIa1k1OWgHZ3vA8g%3D%3D.eUjeTVjmIonZiPCirsBzotjfFDqcsUeqt96utNqqz%2BWEMbfeFDn1Zq%2BD9dE4wyfW) 提到 强引用链: thread -> threadLocalMap -> counter -> MyCounter.class -> WebappClassLocader ,导致WebappClassLoader泄漏。 对这个有疑问。 Class类型被卸载的条件 ![图片](https://wmlx-new-image.oss-cn-shanghai.aliyuncs.com/images/20241106/b686f6a0b00cfb3e92c42c2705049525.png) ## 疑问点是 其中第二点: 加载该类的类加载被回收,是指 类加载器对象被gc。 假设MyCounter.class 由 WebAppClassLoader加载,那么 通过MyCounter.class.getClassLoader() 就可以得到WebAppClassLoader, 而WebAppClalssLoader 被gc的条件必然是没有任何人引用她, 所以 如何做到MyCounter.class 不会引用WebAppClassLoader? 否则是不是 就会出现 WebAppClassLoader一直被MyCounter.class所引用呢? 如果一直被引用的话那么WebAppClassLoader对象就不会被gc,那么MyCounter.class对象自然也不会被gc了。 感觉是鸡生蛋蛋生鸡的问题。 如果说 MyCounter.class 对 WebAppClassLoader对象有强引用, WebAppClassLoader对象又怎么可能会被回收呢。如果WebAppClassLoader对象不被gc,那么MyCOunter.class又怎么会被回收呢? b

阅读量:18

点赞量:0

问AI
我梳理了一下,你现在的问题不是在探讨为什么threadLocal在tomcat中造成了内存泄露,而是只考虑类加载器与类的互引用让你觉得它们无法被卸载对吧 "WebAppClalssLoader 被gc的条件必然是没有任何人引用" 这是准确的吗?假设内存中有一对相互引用的对象,但是他们都没有任何其他的对象所引用,难道JVM就无法回收他们吗? 在不同的GC算法里对这种情况应该都是有所处理的,比如标记清除算法等等,尽管有相互引用,但是由于没有从根对象到达它们的路径,所以还是有可能被回收的。这是回答你的问题。 另外,这篇知乎文章的观点我也不是很认同。使用threadLocal时必须注意线程在threadLocal内持有的对象是否能回收。他的情况是认为通过tomcat对web应用进行reload之后就可以不管不顾了,殊不知他的程序根本没有正确地结束所有的线程,进而线程在threadLocal内持有的对象无法被回收,进而导致整个应用无法被回收。他的内存泄露是reload时不能彻底关闭之前的应用导致的