|
21 | 21 | 上述方式可以达到内存泄漏的目的,因为 ThreadLocal 存储了一个指向类B对象的引用,
|
22 | 22 | 而该对象又保存了一个指向其类的引用,这个类又保存了一个指向其ClassLoader的引用,
|
23 | 23 | 而ClassLoader又保存了一个通过它加载的所有类的引用。
|
24 | | -这种方法在许多的JVM的实现中表现很糟糕,因为Classes和ClassLoader被直接存储在老年代(permgen)并且永远都不会被GC处理。 |
| 24 | +这种方法在许多的JVM的实现中表现更糟糕,因为Classes和ClassLoader被直接存储在老年代(permgen)并且永远都不会被GC处理。 |
25 | 25 |
|
26 | 26 | ******************************下方为个人理解************************************
|
27 | 27 |
|
28 | | -通过一个简单的图来描述上述关系: |
| 28 | +通过一个简单的图来描述上述关系:<br> |
29 | 29 | ThreadLocal.obj ---> B.obj ---> B.class <--> ClassLoader.obj<br>
|
30 | 30 | 注:上图的\*.obj表示\*类的一个实例对象,B.class表示类B的Class对象
|
31 | 31 |
|
32 | 32 | ******************************上方为个人理解************************************
|
33 | 33 |
|
34 | | -这个模式的一个变形:为什么应用容器(例如Tomcat)可以像筛子一样泄漏内存,如果你频繁的重新部署那些可能使用ThreadLocals的应用。 |
35 | | -因为应用容器使用上述所说的线程,每次重新部署应用是,应用容器都会使用一个新的ClassLoader。 |
| 34 | +这个模式的一个变形:如果频繁的重新部署那些可能使用ThreadLocals的应用,应用容器(例如Tomcat)就会像筛子一样泄漏内存。 |
| 35 | +因为应用容器使用上述所说的线程,每次重新部署应用时,应用容器都会使用一个新的ClassLoader。 |
36 | 36 |
|
37 | 37 | 具体代码可以参考:https://gist.github.com/dpryden/b2bb29ee2d146901b4ae
|
38 | 38 |
|
|
0 commit comments