谈下Spring IOC容器为什么不会被GC

前言

JVM的内存是有限的,因此不可能让我们无限地创建对象,JVM GC的诞生就是为了对不再存活的对象进行回收,释放内存的,那么怎样判断对象已死呢?了解过JVM GC的人,可能就知道JVM其实通过可达性分析来判定对象是否存活的,这个算法的基本思路就是通过一系列称为 GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链 ,当一个对象到 GC Roots没有任何引用链相连时,则证明此对象是不可用的。(读者如果对JVM GC感兴趣,推荐看下周志明的《深入理解JAVA虚拟机》)

那么哪些对象是GC Roots呢?这里列举了下:

  • 虚拟机栈(栈帧中的本地变量)中引用的对象。
  • 方法区中类静态属性引用的对象。
  • 方法区中常量引用的对象。
  • 本地方法栈中JNI(Native方法)引用的对象。
  • Thread:已经启动并且没有stop的线程。
  • System class:被bootstrap或者system类加载器加载的类,比如rt.jar里的java.util.*;

整合Spring的web应用启动后,Spring IOC容器为什么不会被GC?

我们可以先启动一个Spring项目,然后用命令生成堆内存:jmap -dump:format=b,file=mydump.hprof 42424 这里的42424是pid,可以用jps命令查看启动的Java进程pid。
然后通过MAT工具进行分析,MAT工具可以当做Eclipse插件使用,也可以单独下载使用,下载MAT
下载完成,启动mat工具,打开刚才的mydump.hprof文件,找到Spring工厂类,查看gc path:在这里插入图片描述
通过图中信息分析,Spring 其gc root 为 Thread,根据图中信息可推断此线程为Tomcat启动,加载容器的线程,此线程未stop,即Spring资源无法被回收。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章