最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring bean不被GC的真正原因及分析

 更新時間:2024年04月29日 10:06:35   作者:Bryant5051  
這篇文章主要介紹了Spring bean不被GC的真正原因及分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

概述

自從開始接觸 Spring 之后,一直以來都在思考一個問題,在 Spring 應(yīng)用的運行過程中,為什么這些 bean 不會被回收?

今天深入探究了這個問題之后,才有了答案。

思考點

大家都知道,一個 bean 會不會被回收,取決于對象存活判定算法。

JVM 底層中使用的是可達性分析算法,拋開 HotSpot 的實現(xiàn)細節(jié)不談,那么一個對象被判定為死亡,應(yīng)該與 GC Root 不存在可達的引用路徑。

所以,Spring 的 bean 肯定是與 GC Root 存在可達的引用路徑,才不會被回收掉

Java 語言對于 GC Root 的定義中,以下幾種對象可以作為 GC Root

  • 虛擬機棧的棧幀中的本地變量表中,引用類型對象所指向的堆中的對象
  • 處于運行中狀態(tài)(RUNNABLE,BLOCKED,WAITING,TIMED_WAITING)的線程對象
  • JDK 自帶的類加載器對象
  • 本地方法所引用的對象
  • JVM 持有的對象,例如基本類型的 Class 對象,NullPointerException 等常用異常對象
  • 被 synchronized 關(guān)鍵字修飾的對象

一般來說,只要是符合上面這幾種規(guī)則的對象,或者能由上面的規(guī)則推導(dǎo)出存在引用的對象,都可以作為 GC Root。

那么 SpringbeanGC Root 是哪一種呢?或者說,找到了 SpringbeanGC Root,就找到了問題的答案。

動手尋找答案

首先新建一個 SpringBoot 應(yīng)用,里面定義了兩個 bean 以及一個啟動類,包結(jié)構(gòu)如下:

然后點擊運行啟動類,啟動完成之后,打開 jvisualVM ,找到對應(yīng)的應(yīng)用,然后點擊生成當(dāng)前dump

然后打開后選擇類,輸入 Hello 過濾類名,找到 HelloWorldService,點擊在實例視圖中顯示,發(fā)現(xiàn)只有一個實例存在,這符合我們的預(yù)期。

最后右鍵點擊這個實例,選擇顯示最近的垃圾回收根節(jié)點,可以觀察到如下的引用路徑:

可以看到,DefaultListableBeanFactoryAnnotationConfigServletWebServerApplicationContext 都是我們比較熟悉的 bean 容器,對應(yīng)的往下找發(fā)現(xiàn)有 ConcurrentHashMap$Node 引用。

我們都知道在 Spring 中,正是這兩個容器(準(zhǔn)確地說是 DefaultListableBeanFactory)中使用 ConcurrentHashMap 存放了實例化好的 bean。 這都是非常符合我們預(yù)期的。

但是在 AbstractApplicationContext 再往上找后,發(fā)現(xiàn)有個叫 ApplicationShutdownHooks 的東西。意思就是說,我們的容器,最終與這個 ApplicationShutdownHooks 的東西扯上了引用關(guān)系。接

著我們翻閱 Spring 源碼進行求證:

發(fā)現(xiàn)在 AbstractApplicationContextregisterShutdownHook 方法中調(diào)用了這一行代碼,而 registerShutdownHook 方法正是在 Spring 容器初始化時要調(diào)用的方法:

這說明在 Spring 容器初始化時,調(diào)用的這個方法,然后在繼續(xù)往里跟蹤這個方法:

最后我們可以發(fā)現(xiàn),AbstractApplicationContext 中的 Thread shutdownHook 變量,最終被放在了 ApplicationShutdownHooks 的這個 map 里面,而這個 map 恰好就是一個靜態(tài)變量。

結(jié)論

所以,Springbean 沒有被回收,正是因為在 AbstractApplicatuonContextregisterShutdownHook 方法中,與 ApplicationShutdownHooks 中的一個靜態(tài)變量建立了可達的引用路徑。

題外話

那么為什么類的靜態(tài)變量可以作為 GC Root 呢?抱著嚴(yán)謹(jǐn)?shù)男膽B(tài),我們繼續(xù)往下求證:

類的靜態(tài)變量屬于類對象,類對象由類加載器進行加載,而類加載器是 GC Root,那么類加載器是不是與被加載的類對象存在引用關(guān)系呢?

翻閱 ClassLoader 類,赫然看到這一段代碼:

public abstract class ClassLoader {
    // The classes loaded by this class loader. The only purpose of this table
    // is to keep the classes from being GC'ed until the loader is GC'ed.
    private final Vector<Class<?>> classes = new Vector<>();
}

注釋一目了然,好家伙!原來類加載器把所有的已加載的類對象都保存在這個容器里面,怪不得類對象和類靜態(tài)變量也屬于 GC Root

最后

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java處理double類型提示2e31的問題解決

    Java處理double類型提示2e31的問題解決

    本文主要介紹了Java處理double類型提示2e31的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • 基于SpringBoot+JWT 實現(xiàn)Token登錄認(rèn)證與登錄人信息查詢功能

    基于SpringBoot+JWT 實現(xiàn)Token登錄認(rèn)證與登錄人信息查詢功能

    本文給大家介紹基于SpringBoot+JWT實現(xiàn)Token登錄認(rèn)證與登錄人信息查詢功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值
    2026-03-03
  • Java獲取文件后綴名的方法小結(jié)

    Java獲取文件后綴名的方法小結(jié)

    在Java開發(fā)中,尤其是Web應(yīng)用或文件處理場景中,獲取文件后綴名是一個高頻需求,無論是文件上傳驗證、類型過濾、格式校驗,還是日志記錄,后綴名的正確提取都是核心基礎(chǔ),本文給大家介紹了Java獲取文件后綴名的方法,需要的朋友可以參考下
    2025-05-05
  • Java串口通信JSerialComm的實現(xiàn)

    Java串口通信JSerialComm的實現(xiàn)

    本文介紹了使用JSerialComm庫進行Java串口通信,包括引入庫的方式、設(shè)置和操作串口、發(fā)送與接收數(shù)據(jù)以及添加數(shù)據(jù)監(jiān)聽器,具有一定的參考價值,感興趣的可以了解一下
    2026-01-01
  • java實現(xiàn)停車場系統(tǒng)

    java實現(xiàn)停車場系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)停車場系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Java JNA庫詳解與本地系統(tǒng)交互實戰(zhàn)記錄(推薦)

    Java JNA庫詳解與本地系統(tǒng)交互實戰(zhàn)記錄(推薦)

    JNA 是一個開源庫,它提供了 Java 程序調(diào)用本地共享庫(如 DLLs 在 Windows 或 .so 文件在 Linux/Unix)的功能,本文給大家介紹Java JNA庫詳解與本地系統(tǒng)交互實戰(zhàn),感興趣的朋友一起看看吧
    2025-11-11
  • 使用Java發(fā)送郵件到QQ郵箱的完整指南

    使用Java發(fā)送郵件到QQ郵箱的完整指南

    在現(xiàn)代軟件開發(fā)中,郵件發(fā)送功能是一個常見的需求,無論是用戶注冊驗證、密碼重置,還是系統(tǒng)通知,郵件都是一種重要的通信方式,本文將詳細介紹如何使用Java編寫程序,實現(xiàn)發(fā)送郵件到QQ郵箱的功能,需要的朋友可以參考下
    2025-03-03
  • SpringBoot獲取客戶端的IP地址的實現(xiàn)示例

    SpringBoot獲取客戶端的IP地址的實現(xiàn)示例

    在Web應(yīng)用程序中,獲取客戶端的IP地址是一項非常常見的需求,本文主要介紹了SpringBoot獲取客戶端的IP地址的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • SpringBoot參數(shù)校驗及原理全面解析

    SpringBoot參數(shù)校驗及原理全面解析

    文章介紹了SpringBoot中使用@Validated和@Valid注解進行參數(shù)校驗的方法,包括基本用法和進階用法,如自定義驗證注解、多屬性聯(lián)合校驗和嵌套校驗,并簡要介紹了實現(xiàn)原理
    2024-11-11
  • 詳解Java8中的Lambda表達式

    詳解Java8中的Lambda表達式

    這篇文章主要介紹了Java8中的Lambda表達式的相關(guān)資料,文中講解非常細致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07

最新評論

宁夏| 洛隆县| 开鲁县| 阿克陶县| 驻马店市| 正宁县| 宜都市| 浦北县| 交城县| 双辽市| 北票市| 望奎县| 普兰店市| 崇明县| 鄂托克前旗| 江川县| 曲靖市| 桂阳县| 沁阳市| 吉林市| 龙胜| 和硕县| 贡嘎县| 蒙自县| 长岛县| 和龙市| 任丘市| 唐海县| 揭东县| 项城市| 静乐县| 绵阳市| 兴化市| 孟连| 新郑市| 赤城县| 日喀则市| 永城市| 房产| 宁明县| 塘沽区|