JVM——類的生命周期

文章目錄

    • 類加載過程
      • 加載
      • 驗證
      • 準備
      • 解析
      • 初始化
    • 卸載

一個類的完整生命周期如下:

在這里插入圖片描述

類加載過程

Class 文件需要加載到虛擬機中之后才能運行和使用,那么虛擬機是如何加載這些 Class 文件呢?

系統加載 Class 類型的文件主要三步:加載->連接->初始化。連接過程又可分為三步:驗證->準備->解析

在這里插入圖片描述

加載

類加載過程的第一步,主要完成下面3件事情:

  1. 通過全類名獲取定義此類的二進制字節流
  2. 將字節流所代表的靜態存儲結構轉換為方法區的運行時數據結構
  3. 在內存中生成一個代表該類的 Class 對象,作為方法區這些數據的訪問入口

虛擬機規范上面這3點并不具體,因此是非常靈活的。比如:“通過全類名獲取定義此類的二進制字節流” 并沒有指明具體從哪里獲取、怎樣獲取。比如:比較常見的就是從 ZIP 包中讀取(日后出現的JAR、EAR、WAR格式的基礎)、其他文件生成(典型應用就是JSP)等等。

一個非數組類的加載階段(加載階段獲取類的二進制字節流的動作)是可控性最強的階段,這一步我們可以去完成還可以自定義類加載器去控制字節流的獲取方式(重寫一個類加載器的 loadClass() 方法)。數組類型不通過類加載器創建,它由 Java 虛擬機直接創建。

類加載器、雙親委派模型也是非常重要的知識點,這部分內容會在后面的文章中單獨介紹到。

加載階段和連接階段的部分內容是交叉進行的,加載階段尚未結束,連接階段可能就已經開始了。

驗證

在這里插入圖片描述

準備

準備階段是正式為類變量分配內存并設置類變量初始值的階段,這些內存都將在方法區中分配。對于該階段有以下幾點需要注意:

  1. 這時候進行內存分配的僅包括類變量(static),而不包括實例變量,實例變量會在對象實例化時隨著對象一塊分配在 Java 堆中。
  2. 這里所設置的初始值"通常情況"下是數據類型默認的零值(如0、0L、null、false等),比如我們定義了public static int value=111 ,那么 value 變量在準備階段的初始值就是 0 而不是111(初始化階段才會賦值)。特殊情況:比如給 value 變量加上了 fianl 關鍵字public static final int value=111 ,那么準備階段 value 的值就被賦值為 111。

基本數據類型的零值:

在這里插入圖片描述

解析

解析階段是虛擬機將常量池內的符號引用替換為直接引用的過程。解析動作主要針對類或接口、字段、類方法、接口方法、方法類型、方法句柄和調用限定符7類符號引用進行。

符號引用就是一組符號來描述目標,可以是任何字面量。直接引用就是直接指向目標的指針、相對偏移量或一個間接定位到目標的句柄。在程序實際運行時,只有符號引用是不夠的,舉個例子:在程序執行方法時,系統需要明確知道這個方法所在的位置。Java 虛擬機為每個類都準備了一張方法表來存放類中所有的方法。當需要調用一個類的方法的時候,只要知道這個方法在方發表中的偏移量就可以直接調用該方法了。通過解析操作符號引用就可以直接轉變為目標方法在類中方法表的位置,從而使得方法可以被調用。

綜上,解析階段是虛擬機將常量池內的符號引用替換為直接引用的過程,也就是得到類或者字段、方法在內存中的指針或者偏移量。

初始化

初始化是類加載的最后一步,也是真正執行類中定義的 Java 程序代碼(字節碼),初始化階段是執行初始化方法 <clinit> ()方法的過程。

對于<clinit>() 方法的調用,虛擬機會自己確保其在多線程環境中的安全性。因為 <clinit>() 方法是帶鎖線程安全,所以在多線程環境下進行類初始化的話可能會引起死鎖,并且這種死鎖很難被發現。

對于初始化階段,虛擬機嚴格規范了有且只有5種情況下,必須對類進行初始化(只有主動去使用類才會初始化類):

  1. 當遇到 new 、 getstatic、putstatic或invokestatic 這4條直接碼指令時,比如 new 一個類,讀取一個靜態字段(未被 final 修飾)、或調用一個類的靜態方法時。
    • 當jvm執行new指令時會初始化類。即當程序創建一個類的實例對象。
    • 當jvm執行getstatic指令時會初始化類。即程序訪問類的靜態變量(不是靜態常量,常量會被加載到運行時常量池)。
    • 當jvm執行putstatic指令時會初始化類。即程序給類的靜態變量賦值。
    • 當jvm執行invokestatic指令時會初始化類。即程序調用類的靜態方法。
  2. 使用 java.lang.reflect 包的方法對類進行反射調用時如Class.forname(“…”),newInstance()等等。 ,如果類沒初始化,需要觸發其初始化。
  3. 初始化一個類,如果其父類還未初始化,則先觸發該父類的初始化。
  4. 當虛擬機啟動時,用戶需要定義一個要執行的主類 (包含 main 方法的那個類),虛擬機會先初始化這個類。
  5. MethodHandle和VarHandle可以看作是輕量級的反射調用機制,而要想使用這2個調用,
    就必須先使用findStaticVarHandle來初始化要調用的類。
  6. 「補充,來自issue745」 當一個接口中定義了JDK8新加入的默認方法(被default關鍵字修飾的接口方法)時,如果有這個接口的實現類發生了初始化,那該接口要在其之前被初始化。

卸載

卸載這部分內容來自 issue#662由 guang19 補充完善。

卸載類即該類的Class對象被GC。

卸載類需要滿足3個要求:

  1. 該類的所有的實例對象都已被GC,也就是說堆不存在該類的實例對象。
  2. 該類沒有在其他任何地方被引用
  3. 該類的類加載器的實例已被GC

所以,在JVM生命周期類,由jvm自帶的類加載器加載的類是不會被卸載的。但是由我們自定義的類加載器加載的類是可能被卸載的。

只要想通一點就好了,jdk自帶的BootstrapClassLoader,ExtClassLoader,AppClassLoader負責加載jdk提供的類,所以它們(類加載器的實例)肯定不會被回收。而我們自定義的類加載器的實例是可以被回收的,所以使用我們自定義加載器加載的類是可以被卸載掉的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41512.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41512.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41512.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis-秒殺

唉 就記得當時搶冰墩墩的時候的秒殺了 我們要注意什么問題呢? 1.幾百萬人在這個瞬間搶冰墩墩 這個瞬間會有大量的請求 服務器要能抗的住 2.不能超賣,就那些冰墩墩 賣多了壓根沒有 好不容易搶到你說沒貨了怕不是要被沖爛 3.避免少賣 攏共就那些 你再少賣點 沒屁了 4.防黃牛…

CentOS系統環境搭建(十五)——CentOS安裝Kibana

centos系統環境搭建專欄&#x1f517;點擊跳轉 關于Elasticsearch的安裝請看CentOS系統環境搭建&#xff08;十二&#xff09;——CentOS7安裝Elasticsearch。 CentOS安裝Kibana 文章目錄 CentOS安裝Kibana1.下載2.上傳3.解壓4.修改kibana配置文件5.授予es用戶權限6.kibana 后臺…

uniapp的UI框架組件庫——uView

在寫uniapp項目時候&#xff0c;官方所推薦的樣式庫并不能滿足日常的需求&#xff0c;也不可能自己去寫相應的樣式&#xff0c;費時又費力&#xff0c;所以我們一般會去使用第三方的組件庫UI&#xff0c;就像vue里我們所熟悉的elementUI組件庫一樣的道理&#xff0c;在uniapp中…

? Spring Clould 配置中心 - Nacos

視頻地址&#xff1a;微服務&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; Nacos配置管理-Nacos實現配置管理&#xff08;P24、P25&#xff09; Nacos除了可以做注冊中心&#xff0c;同樣可以做配置管理來使用。 當微服務部署的實例越來越多&#xff0c…

18萬字應急管理局智慧礦山煤礦數字化礦山技術解決方案WORD

導讀&#xff1a;原文《18萬字應急管理局智慧礦山煤礦數字化礦山技術解決方案WORD》&#xff08;獲取來源見文尾&#xff09;&#xff0c;本文精選其中精華及架構部分&#xff0c;邏輯清晰、內容完整&#xff0c;為快速形成售前方案提供參考。 目 錄 第一章 項目概述 1.1項目…

《Go 語言第一課》課程學習筆記(七)

代碼塊與作用域&#xff1a;如何保證變量不會被遮蔽&#xff1f; 什么是變量遮蔽呢&#xff1f;package mainimport ("fmt""github.com/google/uuid""github.com/sirupsen/logrus" )func main() {fmt.Println("hello, world")logrus.…

私域新零售商業模式成功的八大要素

從事互聯網行業多年以來&#xff0c;遇到客戶問最多的一個問題&#xff0c;就是什么樣的模式火呀&#xff1f;在設計一個商業模式時&#xff0c;不單單只是考慮資金和人脈等等資源的&#xff0c;其實還是需要遵循這八大原則&#xff0c;它包括&#xff1a;客戶價值最大化原則、…

PyTorch學習筆記(十三)——現有網絡模型的使用及修改

以分類模型的VGG為例 vgg16_false torchvision.models.vgg16(weightsFalse) vgg16_true torchvision.models.vgg16(weightsTrue) print(vgg16_true) vgg16_true.classifier.add_module("add_linear",nn.Linear(1000,10)) print(vgg16_true) vgg16_false.classifie…

C#學習,委托,事件,泛型,匿名方法

目錄 委托 聲明委托 實例化委托 委托的多播 委托的用途 事件 通過事件使用委托 聲明事件 泛型 泛型的特性 泛型方法 泛型的委托 匿名方法 編寫匿名方法的語法 委托 類似于指針&#xff0c;委托是存有對某個方法的引用的一種引用類型變量&#xff0c;引用可以在運…

vue中使用faker庫生成指定類型的隨機數據

介紹 Faker.js 是十分流行的 Node.js 工具庫&#xff0c;2022年初&#xff0c;Faker.js的作者突然刪庫跑路&#xff0c;導致眾多應用程序崩潰&#xff0c;為了繼續使用Faker的功能&#xff0c;社區的幾位開發者組成團隊決定創建并維護新項目faker-js/faker&#xff0c;現其已成…

Docker+Selenium Grid搭建自動化測試平臺

安裝docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager –add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install docker-ce -y Create a Docker Network docker network create grid 下載鏡像 hu…

laravel-admin之 解決上傳圖片不顯示 $form->image(‘image‘); 及 $grid->column(‘image‘);

參考 https://blog.csdn.net/u013164285/article/details/106017464 $grid->column(‘image’)->image(‘http://wuyan.cn’, 100, 100); // //設置服務器和寬高 圖片上傳的域名 上傳的圖片不顯示 在 這里設置了圖片的上傳路徑 在這里設置 域名 就可以回顯圖片

【計算機視覺|生成對抗】帶條件的對抗網絡進行圖像到圖像的轉換(pix2pix)

本系列博文為深度學習/計算機視覺論文筆記&#xff0c;轉載請注明出處 標題&#xff1a;Image-to-Image Translation with Conditional Adversarial Networks 鏈接&#xff1a;Image-to-Image Translation with Conditional Adversarial Networks | IEEE Conference Publicati…

如何學習正則表達式

正則是什么&#xff0c;能做什么&#xff1f; 正則&#xff0c;就是正則表達式&#xff0c;英文是 Regular Expression&#xff0c;簡稱 RE。顧名思義&#xff0c;正則其實就是一種描述文本內容組成規律的表示方式。 在編程語言中&#xff0c;正則常常用來簡化文本處理的邏輯…

Android DataStore:安全存儲和輕松管理數據

關于作者&#xff1a;CSDN內容合伙人、技術專家&#xff0c; 從零開始做日活千萬級APP。 專注于分享各領域原創系列文章 &#xff0c;擅長java后端、移動開發、人工智能等&#xff0c;希望大家多多支持。 目錄 一、導讀二、概覽三、使用3.1 Preferences DataStore添加依賴數據讀…

LVS負載均衡集群-NAT模式部署

集群 集群&#xff1a;將多臺主機作為一個整體&#xff0c;然后對外提供相同的服務 集群使用場景&#xff1a;高并發的場景 集群的分類 1.負載均衡器集群 減少響應延遲&#xff0c;提高并發處理的能力 2&#xff0c;高可用集群 增強系統的穩定性可靠性&…

封裝vue2局部組件都要注意什么

一. 關于局部組件組成的三個部分&#xff08;template, script, style&#xff09; template > 組件的模板結構 &#xff08;必選&#xff09; 每個組件對應的模板結構&#xff0c;需要定義到template節點中 <template><!-- 當前組件的dom結構&#xff0c;需…

Java SPI加載機制

SPI加載機制 SPI&#xff08;Service Provider Interface&#xff09;是一種通過外界配置來加載具體代碼內容的技術手段。SPI是JDK內置的一種服務提供發現機制&#xff0c;用于實現框架的擴展和組件替換。 在SPI中&#xff0c;框架提供一整套接口&#xff0c;使用者實現這些接…

React源碼解析18(8)------ 實現單節點的Diff算法

摘要 經過之前的幾篇文章&#xff0c;我們已經實現了一個可以進行更新渲染的假React。但是如果我們把我們的jsx修改成這樣&#xff1a; function App() {const [age, setAge] useState(20)const click function() {setAge(age 1)}return age % 2 0 ? jsx("div"…

學習紅外成像儀開發注意要點

學習紅外成像儀開發注意要點 三河凡科科技飛訊紅外成像儀開發學習注意要點 紅外成像儀是一種高級的光學設備&#xff0c;可用于探測、分析和顯示紅外輻射&#xff0c;它廣泛應用于醫學、軍事、石油、礦產資源勘探等領域。紅外成像儀的開發需要注意以下幾個方面&#xff1a; 1…