JVM 雙親委派模型以及垃圾回收機制

目錄

1. JVM 內存區域劃分

2. JVM 中類加載的過程

1) 類加載的基本流程

2) 雙親委派模型

3. JVM 中垃圾回收機制

1) 找到垃圾

a) 引用計數

b) 可達性分析

2) 釋放垃圾


1. JVM 內存區域劃分

一個運行起來的 Java 進程,其實就是一個 JVM 虛擬機。

而進程是資源分配的基本單位,所以 JVM 就首先會申請一大塊內存,然后把這個內存劃分成不同的區域,每個區域都有不同的作用。

JVM 內存區域劃分成以下四個部分:

1. 方法區 (1.7 及之前) / 元數據區 (1.8 開始)

方法區存儲的內容,就是類對象。( .class 文件加載到內存之后,就成了類對象)

2. 堆

這里存儲的內容,就是代碼中 new 的對象。

堆是占據空間最大的區域。

3. 虛擬機棧(就是平常我們所說的棧)

這里存儲的內容,就是代碼執行過程中,方法之間的調用關系。

4. 程序計數器

是個比較小的空間,主要用來存放一個 "地址",這個地址,就表示了下一條要執行的指令,在內存中的哪個地方(方法區里)。

每個方法,里面的指令,都是以二進制的形式, 保存到類對象中的。

?剛開始調用方法的時候,程序計數器記錄的就是方法的入口的地址。

隨著一條一條的執行指令,每執行一條指令,程序計數器的值都會自動更新,去指向下一條指令。

程序計數器和虛擬機棧是每個線程都有一份,而堆和方法區在 JVM 進程中是只有一份的。

在 Java 里,每個線程都有自己私有的棧空間。

2. JVM 中類加載的過程

1) 類加載的基本流程

java 代碼會被編譯成 .class 文件(包含了一些字節碼),java 程序想要運行起來,就需要讓 JVM 讀取到這些 .class 文件,并把里面的內容,構造成類對象,保存到內存的方法區中。?

官方文檔把類加載的過程主要分成了 5 個步驟。

1. 加載:找到 .class 文件,打開文件,讀取文件內容。

往往代碼中,會給定某個類的 "全限定類名"(比如 java.lang.String,java.util.ArrayList) ,JVM 就會根據這個類名,在一些指定的目錄范圍內查找。

2. 驗證: .class 文件是一個二進制的格式。(某個字節,都是有某些特定含義的),就需要驗證你當前讀到的這個格式是否符合要求。

3. 準備:給類對象分配內存空間(最終的目標,是要構造出類對象)

這里只是分配空間,還沒有初始化,此時這個空間上的內存的數值,就是全 0 的,此時如果嘗試打印類的 static 成員,就是全 0 的。

4. 解析:針對類對象中包含的字符串常量進行處理,進行一些初始化操作。

java 代碼中用到的字符串常量,在編譯之后,也會進入到 .class 文件中。

5. 初始化:針對類對象進行初始化。

把類對象中需要的各個屬性都設置好。

還需要初始化號 static 成員

還需要執行靜態代碼塊

以及可能還需要加載一下父類。

總結類加載的基本流程:

1. 加載:找到 .class 文件,打開 .class 文件,讀取 .class 文件

2. 驗證:驗證當前 .class 文件格式是否正確

3. 準備:給類對象分配內存空間

4. 解析:將符號引用替換成直接引用

5. 初始化:初始化類對象

2) 雙親委派模型

屬于類加載中第一個步驟 "加載" 中的一個環節,是負責根據全限定類名,來找到 .class 文件的。

類加載器,是 JVM 中的一個模塊(專門負責類加載的操作)。

JVM 中,內置了三個類加載器:

1. BootStrap ClassLoader? ? ? ? ? ?爺

2. Extension ClassLoader? ? ? ? ? ?父

3. Application ClassLoader? ? ? ? ?子

這個父子關系,不是繼承構成的,而是這幾個 ClassLoader 里有一個 parent 這樣的屬性,指向了一個 父 "類加載器"。

程序員也可以手動創建出新的類加載器。

所以說,雙親委派模型,就是一個查找優先級的問題,先找標準庫,再找擴展庫,最后找第三方庫。

3. JVM 中垃圾回收機制

在 Java 中,new 一個對象,就是 "動態內存申請",在 C 語言中,使用 malloc 這種 "動態內存申請" 的函數,使用完之后,就需要手動調用 free 釋放內存,如果不釋放,就會出現內存泄露這樣的問題,而在 Java 中就不用手動釋放內存,因為 JVM 自動判定,是否某個對象已經不再使用了,并幫我們進行釋放不再使用的對象的內存了。像這種不再使用的對象,就稱之為 "垃圾",這種機制,也就叫做 GC 垃圾回收機制。

GC 也有缺陷:

1. 系統開銷,需要有一個/一些特定的線程,不停的掃描你內存中的所有的對象,看是否能夠回收,此時是需要額外的內存和 CPU 資源的。

2. 效率問題,這樣的掃描線程,不一定能夠及時的釋放內存 (掃描總是有一定周期的),一旦同一時刻,出現大量的對象都需要被回收,GC 產生的負擔就會很大,甚至引起整個程序都卡頓 (STW 問題? ? stop? ?the? ?world)

但是 GC 屬于大勢所趨,Python,PHP,Go.... 都是具有 GC 機制的。

GC 是垃圾回收,GC 回收的目標,其實是 內存中的 對象。

對于 Java 來說,就是 new 出來的這些對象。

棧里的局部變量,是跟隨著棧幀的生命周期走的。(方法執行結束,棧幀銷毀,內存自然釋放)

靜態變量,生命周期就是整個程序,這就意味著 靜態變量 是無需釋放的。

因此真正需要 gc 釋放的對象就是 堆 上的對象。

gc 可以理解成兩個大的步驟:

1. 找到垃圾

2. 釋放垃圾

1) 找到垃圾

在 GC 的圈子中,有兩種主流的方案:1. 引用計數? ? ?2. 可達性分析 (Java?采用的是這種)

a) 引用計數

new 出來的對象,單獨安排一塊空間,來保存一個計數器。

b) 可達性分析

可達性分析,本質上是一個時間換空間這樣的手段。

有一個/一組線程,周期性的掃描代碼中的所有對象。

從一些特定的對象出發,盡可能的進行訪問的遍歷,把所有能夠訪問到的對象,都標記成 "可達",反之,經過掃描之后,未被標記成 "可達" 的對象,就是垃圾了。

就跟二叉樹的遍歷差不多,只不過不是二叉樹,而是 N 叉樹。

2) 釋放垃圾

有三種基本的思路:

1. 標記清除

是一種比較簡單粗暴的方式。

2. 復制算法

第二種思路,就是解決,剛剛標記清除出現的內存碎片的辦法。

通過復制的方式,把有效的對象,歸類到一起,再統一釋放剩下的空間。

3. 標記整理

既能夠解決內存碎片的問題,又能夠處理復制算法中利用率。

類似于順序表刪除元素的搬運操作。

實際上,JVM 采取的釋放思路,是上述基礎思路的結合體。

分代回收:

分代回收,對象能活過的 GC 掃描輪次越多,就是越老。

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

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

相關文章

ansible自動化運維(四)jinjia2模板

Jinjia2模板 前面說到playbook組成的時候,有介紹到template模塊,而template模塊對模板文件進行渲染時,使用的就是jinja2模板引擎,jinja2本身就是基于python的模板引擎,所以下面先來了解一下jinjia2模板的一些用法 基…

通過k-means對相似度較高的語句進行分類

本文介紹了如何使用K-Means算法對相似度較高的語句進行分類,并附上java案例代碼 import java.util.ArrayList; import java.util.List; import java.util.Random;public class KMeansTextClustering {public static void main(String[] args) {// 初始化語句數據集…

Oracle 19c rac 補丁升級,從19.7 to19.22-集群

1. 補丁包概述 數據庫環境 角色 數據庫 IP地址 數據庫版本 主機名 數據庫名稱 源端 RAC 172.30.21.166/167 19.7 hfcwdb66/hfcwdb67 hfdb 將以下補丁包上傳到/soft下 上傳到兩個節點的soft目錄下:p6880880_190000_Linux-x86-64.zip (更新o…

Windows安裝Jira

下載 Download Jira Data Center | Atlassian https://product-downloads.atlassian.com/software/jira/downloads/atlassian-jira-software-10.3.0-x64.exe 以管理員身份安裝,否則彈出以下提醒 創建和配置MySQL數據庫:參照 Connecting Jira applicat…

uniapp - 微信小程序

一、background-image 大圖不顯示的問題 解決方法: 1、使用網絡地址;2、使用 base64 urlTobase64(filePath) {// #ifdef MP-WEIXINlet img ${filePath},imgBase64 wx.getFileSystemManager().readFileSync(img, "base64"),base64Url data:…

DETR: End-to-End Object Detection with Transformers論文學習

論文地址:https://arxiv.org/pdf/2005.12872 代碼地址:https://github.com/facebookresearch/detr 相關學習視頻:https://space.bilibili.com/94779326/lists?sid1531941 標題前言: DETR 是 Facebook 團隊于 2020 年提出的基于…

LeetCode 24反轉鏈表

單鏈表反轉:詳細解析與代碼實現 在數據結構的學習過程中,鏈表是一個非常重要且有趣的部分,而單鏈表的反轉操作更是常考的基礎知識點。今天就來和大家詳細講講如何實現單鏈表的反轉,并通過代碼示例來加深理解呀。 題目 給定單鏈…

Redis學習筆記之——學習計劃

Redis——Remote Dictionary Server,開源、基于內存、速度快、key-value... Redis做為一個高性能的鍵值存儲系統,廣泛應用于緩存、會話存儲、分布式鎖以及其他需要快速訪問的數據場景中。熟悉掌握redis,似乎已成為廣大碼農們必備的一項技能。…

網絡安全教學博客(二):常見網絡安全威脅剖析

在上一篇博客中,我們了解了網絡安全的基礎概念和重要性。今天,讓我們深入探討一下常見的網絡安全威脅,以便我們能夠更好地識別和防范它們。 惡意軟件(Malware) 病毒(Virus):病毒是一…

Vue3狀態管理:Pinia架構設計分析

Vue3狀態管理:Pinia架構設計分析 介紹 在Vue.js開發中,狀態管理是一個非常重要的部分。隨著Vue3的發布,Pinia作為一種新的狀態管理架構也相繼問世。本文將對Pinia架構進行深入分析,幫助讀者了解其設計原理、特點以及在實際項目中的應用。 架構…

【IDEA】啟動報錯

今天啟動IDEA報錯 報錯信息: Cannot connect to already running IDE instance. Exception: Process 5,444 is still running 打開任務管理器,關掉進程ID5444的任務

socket編程UDP-實現停等機制(接收確認、超時重傳)

在下面博客中,我介紹了利用UDP模擬TCP連接、按數據包發送文件的過程,并附上完整源碼。 socket編程UDP-文件傳輸&模擬TCP建立連接脫離連接(進階篇)_udp socket發送-CSDN博客 下面博客實現的是滑動窗口機制: sock…

uniapp小程序的錨點定位(將頁面滾動到目標位置)

小程序中,a頁面跳轉到b頁面,跳轉后滾動定位到b頁面的特定位置。 1.uni.pageScrollTo傳遞一個scrollTop參數可以滾動到特定位置。2.可以通過 uni.createSelectorQuery()等獲取定位元素的位置信息。3.uni.getSystemInfoSync()獲取設備的導航欄和狀態欄高度…

php基礎:命名空間

1.PHP 命名空間可以解決以下兩類問題: 1.用戶編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字沖突。 2.為很長的標識符名稱(通常是為了緩解第一類問題而定義的)創建一個別名(或簡短)的名稱,以提高源代碼的可讀…

分布式 CAP理論 總結

前言 相關系列 《分布式 & 目錄》《分布式 & CAP理論 & 總結》《分布式 & CAP理論 & 問題》 分布式 分布式的核心是將大型業務拆解成多個子業務以使之在不同的機器上執行。分布式是用于解決單個物理機容量&性能瓶頸問題而采用的優化手段&#xf…

python xpath解析筆記

與bs4的區別 bs4有很多屬性和方法,而xpath只有一個方法,是通過不同的xpath表達式實現很多功能的。 html例子 定位 tree.xpath(‘/html/head/title’) 返回列表。 開頭的斜杠表示從根節點遍歷。 中間的斜杠表示層級。(相當于bs4中的>…

Q學習(Q-Learning)詳解

?作者簡介:2022年博客新星 第八。熱愛國學的Java后端開發者,修心和技術同步精進。 🍎個人主頁:Java Fans的博客 🍊個人信條:不遷怒,不貳過。小知識,大智慧。 💞當前專欄…

樹狀數組詳解

概述 樹狀數組(Binary Indexed Tree,簡稱BIT),是一種數據結構,用于處理區間查詢和更新問題。它是一種可以高效地在對數級別時間復雜度內進行單點更新和區間查詢的數據結構。樹狀數組通常用于解決以下兩類問題&#xf…

freeswitch(開啟支持MCU視頻會議,使用mod_av模塊)

親測版本centos 7.9系統–》 freeswitch1.10.9 本人freeswitch安裝路徑(根據自己的路徑進入) /usr/local/freeswitch/etc/freeswitch場景說明: 有些場景想使用視頻會議MCU融合畫面進行開會使用方法: 第一步:下載插件 yum install -y epel-release yum install

【大數據技術基礎】【記錄Ubuntu 16.04升級到18.04】Ubuntu的一個版本升級到另一個版本

在 Ubuntu 操作系統中進行軟件更新和系統升級 Ubuntu Kylin 16.04 LTS 系統進行系統升級到 Ubuntu 18.04.6 LTS 版本 升級提示:系統彈出提示框,告知用戶有新版本的 Ubuntu 可用,詢問用戶是否想要升級。 認證窗口:顯示了一個認證…