欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Spring如何避免被JVM 垃圾回收

 更新時(shí)間:2023年11月16日 09:15:23   作者:五陽(yáng)神功  
如果Spring 被回收掉,Spring管理的bean全部會(huì)被回收,那我們的Java應(yīng)用不就被一鍋端了嗎?所以本文小編將和大家一起聊聊Spring如何避免被JVM垃圾回收,需要的朋友可以參考下

回顧一下,垃圾回收的基礎(chǔ)知識(shí)

在Java堆中,存放著所有Java的對(duì)象實(shí)例。在進(jìn)行垃圾收集之前,JVM需要確定哪些對(duì)象已經(jīng)不被使用(即垃圾),哪些對(duì)象仍然被使用。為了判斷對(duì)象是否是“垃圾”,JVM采用了可達(dá)性分析算法。

可達(dá)性分析算法 是指通過(guò)指定 GC Root 根對(duì)象,從根對(duì)象開(kāi)始搜索引用的對(duì)象,通過(guò)引用鏈條,層層遍歷鏈條上的對(duì)象,可以到達(dá)的對(duì)象不可被垃圾回收。而最終沒(méi)有被搜索遍歷到的對(duì)象,則為 不可達(dá)對(duì)象,應(yīng)該被垃圾回收。

JVM中的 GC Root根對(duì)象包括如下:

  • 虛擬機(jī)棧引用的對(duì)象
  • 本地方法棧內(nèi)JNI(本地方法)引用的對(duì)象
  • 方法區(qū)中類靜態(tài)屬性引用的對(duì)象
  • 方法區(qū)中常量引用的對(duì)象
  • Java虛擬機(jī)內(nèi)部的引用

如果 Spring 想不被垃圾回收,那么Spring一定要確保自己被以上 GC Root引用,以上五個(gè),任意一個(gè)即可。

接下來(lái),我們將分析Spring 源碼!找到Spring不被垃圾回收的奧秘!

啟動(dòng)Spring Boot應(yīng)用

以下代碼啟動(dòng)了一個(gè)Spring Boot應(yīng)用,這是官方推薦的啟動(dòng)方式,通過(guò)注解的方式,把啟動(dòng)類傳遞給 SpringApplication ,調(diào)用run 方法,啟動(dòng)Spring Boot。

@RestController
@SpringBootApplication
public class MyApplication {

    @RequestMapping("/")
    String home() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

需要說(shuō)明的是,run方法在Spring boot啟動(dòng)成功后,會(huì)立即返回,不會(huì)被阻塞。所以 main 線程在啟動(dòng)Spring boot后,將退出……

由于Spring Boot會(huì)啟動(dòng)Jetty/Tomcat等其他線程池,所以Java應(yīng)用并不會(huì)退出。因?yàn)镴ava進(jìn)程退出條件之一是:所有非守護(hù)線程全部退出,則JVM退出,所以只有 main 線程退出,其他業(yè)務(wù)線程還存在情況下,Java不會(huì)退出。

由此可見(jiàn),main 線程在啟動(dòng) Spring Boot后,并不會(huì)一直持有 Spring boot 對(duì)象引用,官方文檔里也沒(méi)有 強(qiáng)調(diào),一定要保持 main 線程 不退出。Spring Boot需要把自己交到其他對(duì)象手中,確保自己不被回收!

那么如何保證 Spring Boot不被垃圾回收呢?我需要從 SpringApplcaition 內(nèi)部找原因!

Spring Boot 和 Tomcat

從上面的代碼可以看到 Spring Boot控制了Java應(yīng)用的入口,而Web容器 Tomcat等被Spring 管理,如果Spring不會(huì)被垃圾回收,那么Tomcat就不用擔(dān)心被垃圾回收。

而在Spring Boot之前的Web應(yīng)用,都是將Java項(xiàng)目打包到Tomcat容器中執(zhí)行。那時(shí)候 Spring MVC和Spring 是要被Tomcat容器管理的,所以那時(shí)的Spring項(xiàng)目不用擔(dān)心 被垃圾回收的問(wèn)題。

而現(xiàn)在 Tomcat和 Spring boot的角色互換,決定了 Spring Boot應(yīng)用必須要處理好垃圾回收問(wèn)題!

探究Spring Boot代碼

創(chuàng)建和啟動(dòng)上下文

下圖是 SpringApplication.run方法的源代碼,run 方法主要執(zhí)行兩步,創(chuàng)建 Spring 上下文和啟動(dòng)上下

刷新上下文的奧秘

在Spring Boot刷新上下文的代碼中,首先調(diào)用 Spring Application.refresh方法啟動(dòng)Spring 上下文。然后 Spring boot就把 Close 方法注冊(cè)到 Java shutdownHook 關(guān)閉鉤子程序中!

基本上可以破案了!

因?yàn)镾pring Boot控制了Java程序的入口,所以要負(fù)責(zé)整個(gè)項(xiàng)目的關(guān)閉流程,于是它 注冊(cè)了Java關(guān)閉鉤子。

接下來(lái),我們看一下注冊(cè)關(guān)閉鉤子,會(huì)被 GC Root引用到嗎?

關(guān)閉鉤子

add 方法,將鉤子程序注冊(cè)到 一個(gè)容器中!

可以看到 Thread 類型的 鉤子程序,被保存在 hooks Map 中。

而hooks列表的類型定義是 static 類型的。 static 變量都是GC Root。

總結(jié)

Spring Boot 在啟動(dòng)時(shí)會(huì)將關(guān)閉流程注冊(cè)到 Java 關(guān)閉鉤子中,并通過(guò)關(guān)閉鉤子線程引用到 Spring 上下文。

關(guān)閉鉤子會(huì)被保存在一個(gè) static 靜態(tài)類型的 Map 中,這個(gè) Map 在 GC Root 上。

因此,Spring Boot 不被垃圾回收的關(guān)鍵是在啟動(dòng)時(shí)注冊(cè)了關(guān)閉鉤子。

破案了,spring永遠(yuǎn)不會(huì)被垃圾回收。

以上就是詳解Spring如何避免被JVM 垃圾回收的詳細(xì)內(nèi)容,更多關(guān)于Spring避免被JVM垃圾回收的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • spring中使用@Autowired注解無(wú)法注入的情況及解決

    spring中使用@Autowired注解無(wú)法注入的情況及解決

    這篇文章主要介紹了spring中使用@Autowired注解無(wú)法注入的情況及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • MyBatis中特殊符號(hào)的轉(zhuǎn)義

    MyBatis中特殊符號(hào)的轉(zhuǎn)義

    編寫SQL中會(huì)用到<,>,,>= 等,但是在mybatis中不可以這么寫,與xml文件的元素沖突,所以需要轉(zhuǎn)義,本文主要介紹了MyBatis中特殊符號(hào)的轉(zhuǎn)義,主要介紹了兩種轉(zhuǎn)義方式,感興趣的可以了解一下
    2024-01-01
  • PowerJob的AbstractScriptProcessor實(shí)現(xiàn)類工作流程源碼解讀

    PowerJob的AbstractScriptProcessor實(shí)現(xiàn)類工作流程源碼解讀

    這篇文章主要為大家介紹了PowerJob的AbstractScriptProcessor源碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Java編程中的性能優(yōu)化如何實(shí)現(xiàn)

    Java編程中的性能優(yōu)化如何實(shí)現(xiàn)

    這篇文章主要介紹了Java編程中的性能優(yōu)化如何實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • spring?IOC容器的Bean管理XML自動(dòng)裝配過(guò)程

    spring?IOC容器的Bean管理XML自動(dòng)裝配過(guò)程

    這篇文章主要為大家介紹了spring?IOC容器Bean管理基于XML的自動(dòng)裝配過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Java8?LocalDateTime時(shí)間日期類使用實(shí)例詳解

    Java8?LocalDateTime時(shí)間日期類使用實(shí)例詳解

    本文從 LocalDateTime 類的創(chuàng)建、轉(zhuǎn)換、格式化與解析、計(jì)算與比較以及其他操作幾個(gè)方面詳細(xì)介紹了 LocalDateTime 類在 Java 8 中的使用,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • 關(guān)于jvm內(nèi)存如何查看

    關(guān)于jvm內(nèi)存如何查看

    本文介紹了如何在Java虛擬機(jī)(JVM)中進(jìn)行內(nèi)存管理,包括查看JVM內(nèi)存情況的常用方法和工具,這些方法包括使用JDK自帶的工具如jps、jstat、jmap和jconsole,以及一些第三方監(jiān)控工具如Prometheus、Grafana和ElasticStack等,通過(guò)這些方法
    2024-09-09
  • Java8中新判空方法之Optional類的使用詳解

    Java8中新判空方法之Optional類的使用詳解

    Opitonal類就是Java提供的為了解決大家平時(shí)判斷對(duì)象是否為空用的。本文將通過(guò)示例為大家講解一下Optional類的使用,感興趣的可以收藏一下
    2022-12-12
  • Java遍歷Map集合的方法(最新推薦)

    Java遍歷Map集合的方法(最新推薦)

    這篇文章主要介紹了Java遍歷Map集合的方法,遍歷map的key集合然后通過(guò)key獲取value,本文給大家講解的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • java多線程讀取多個(gè)文件的方法

    java多線程讀取多個(gè)文件的方法

    這篇文章主要為大家詳細(xì)介紹了java多線程讀取多個(gè)文件的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評(píng)論