談下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資源無法被回收。

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