關于什么是 JVM

關于什么是 JVM,看看普通?和??的回答。

普通人

JVM 就是 Java 虛擬機,是?來運?我們平時所寫的 Java 代碼的。優點是它會

?動進?內存管理和垃圾回收,缺點是?旦發?問題,要是不了解 JVM 的運?

機制, 就很難排查出問題所在。

高手

JVM 全稱是 Java 虛擬機,在聊什么是 JVM 之前,我們不妨看?下這張圖。

image-20231129202929721

從這張圖中可以看出 JVM 所處的位置,同時也能看出它兩個作用:

l 運?并管理 Java 源碼?件所?成的 Class?件,

l 在不同的操作系統上安裝不同的 JVM,從?實現了跨平臺的保證。

?般情況下,對于開發者??,即使不熟悉 JVM 的運?機制并不影響業務代碼的開發,因為在安裝完 JDK 或者 JRE 之后,其中就已經內置了 JVM,所以只需要將 Class?件交給 JVM 運?即可。

但當程序運?的過程中出現了問題,?這個問題發生在 JVM 層?的,那我們就需要熟悉 JVM 的運?機制,才能迅速排查并解決 JVM 的性能問題。

我們先看下目前主流的 JVM HotSpot 的架構圖,通過這張架構圖,我們可以看出 JVM 的大致流程是把一個 class 文件通過類加載器加載進系統,然后放到不同的區域,通過編譯器編譯。

image-20231129203101403

第一個部分 Class Files

在 Java 中,Class?件是由源碼?件?成的,?于源碼?件的內容,是每個 Java開發者在 JavaSE 階段的必備知識,這?就不再贅述了,我們可以關注?下 Class?件的格式,?如其中的常量池、成員變量、?法等,這樣就能知道 Java 源碼內容在 Class?件中的表示?式

第二個部分 Class Loader Subsystem 即類加載機制

Class?件加載到內存中,需要借助 Java 中的類加載機制。類加載機制分為裝載、鏈接和初始化,其主要就是對類進?查找、驗證以及分配相關的內存空間和賦值

第三個部分 Runtime Data Areas 也就是通常所說的運?時數據區

其解決的問題就是 Class?件進入內存之后,該如何進?存儲不同的數據以及數據該如何進?扭轉。比如:Method Area 通常會儲存由 Class?件常量池所對應的運?時常量池、字段和?法的元數據信息、類的模板信息等;Heap 是存儲各種 Java 中的對象實例;Java Threads 通過線程以棧的?式運?加載各個?法;Native Internal Thread 可以理解為是加載運?native 類型的?法;PC Register則是保存每個線程執??法的實時地址。

這樣通過運?時數據區的 5 個部分就能很好地把數據存儲和運?起來了

第四個部分 Garbage Collector 也就是通常所說的垃圾回收

就是對運?時數據區中的數據進?管理和回收。回收機制可以基于不同的垃圾收集器,?如 Serial、Parallel、CMS、G1、ZGC 等,可以針對不同的業務場景選擇不同的收集器,只需要通過 JVM 參數設置 即可。如果我們打開 hotspot 的源碼,可以發現這些收集器其實就是對于不同垃圾收集算法的實現,核?的算法有3 個:標記-清除、標記-整理、復制

  • 標記-清除:標記-清除算法即先標記處待回收的垃圾對象,然后回收其內存區域。

    這種算法存在兩個缺點:一是這回收過程中需要大量標記,清除動作。隨著堆中對象數量的增長,執行效率越來越低;二是會產生內存碎片,導致在分配大對象時有可能沒有連續的內存,提前觸發再一次垃圾回收。

  • 標記-整理:標記-復制算法在對象存活率較高時,就要隨之進行更多的復制操作,效率也隨之降低。同時如果不想浪費一半的內存空間,就要提供上述的逃生門機制,需要有其他內存空間托底。因此這種算法并不適合對老年代進行回收。

    標記-整理算法通常用來回收老年代,它的過程是這樣的:在發生老年代回收時,首先標記存活的對象,然后將存活對象向內存的一端移動,最后清理掉邊界以外的內存區域。

  • 標記-復制:標記-復制算法即先將堆劃分為兩個區域,新建對象時只使用其中一個區域分配內存,發生 GC 時先標記存活的對象,然后將存活的對象復制到另一塊空間中,然后再清空之前的空間。

    對象存活的數量較多時,需要做大量的復制操作,將會產生大量的空間復制開銷。但是在對象存活數量較少時,只需復制少量的對象,然后一次性清理之前使用的空間。在復制時只需按照順序分配另一塊的內存即可,不會產生內存碎片問題,算法簡單高效,標記-復制算法特別適合對于年輕代的垃圾回收

    這種算法最大的缺點顯而易見:分配對象時只使用了一半空間,有很嚴重的空間浪費。

    針對這個問題,其實可以通過調整前后兩塊內存空間的占比來優化,具體的做法是:在 JVM 中,將堆的空間主要分為兩部分,年輕代和老年代,同時對于年輕代又劃分為 Eden 區域、From 區域和 To 區域。

    image-20231129204206762

    新建的對象被分配到 Eden Space 中,當 Eden 區域空間滿時,就觸發一次 Young GC,已經不被使用的做回收處理,而仍然被使用的則被復制到 From 區域。經過這個過程,整個Eden區域就是空閑的,如果有新的對象,就 Eden 區域中創建。如果Eden區域的內存再次被用完,就再一次觸發了 Young GC ,這時就將 Eden 區域和 From 區域中還在使用的對象復制到 To 區域。下一次 Young GC 則是將 Eden 區域和 To 區域中還在使用的對象全部復制到 From 區域。

    如此,經過多次 Young GC 后,會存在某些對象在 From 區域和 To 區域進行多次復制,如果超過某個閾值對象仍然沒有釋放,則將這些對象復制到 Old Generation。如果Old Generation 區域也用完之后,就會觸發 Full GC ,全量回收會對系統的性能造成非常大的影響,所以可以根據各應用的特點和對象的生命周期來設置一個合理的年輕代與老年代的大小值,盡量減少 Full GC。

    在 HotSpot 虛擬機中,默認 Eden 和 Survivor(指其中的一塊) 的大小比例是 8 :1,即只浪費了 10 % 的空間。當 Survivor 的空間無法存儲仍在存活的對象時,會有類似逃生門的機制,直接進入老年代空間。

第五個部分是 JIT Compiler 和 Interpreter

通俗理解就是翻譯器,Class 的字節碼指令通過 JIT Compiler 和 Interpreter 翻譯成對應操作系統的 CPU 指令,只不過可以選擇解釋執?或者編譯執?,在HotSpot JVM 默認采用的是這兩種?式的混合。

image-20231129203351511

第六就是 JNI 的技術

如果我們想要找 Java 中的某個 native?法是如何通過 C 或者 C++實現的,那么可以通過 Native Method Interface 來進?查找,也就是所謂的 JNI 技術。

通過官?上給出的 HotSpot 架構圖,我們就能夠知道 JVM 到底是如何運行的了,當然在實際操作的過程中我們可以借助?些 JVM 參數:

image-20231129203511665

和?些常?的 JDK 常?命令

image-20231129203543082

再結合 JDK 常??具以及第三?的?些?具

image-20231129203609897

我們就可以優雅地分析 JVM 出現的常?問題并對其進?調優。

以上就是我對 JVM 的理解。

好的,看完高手的回答后,相信每位看完視頻的小伙伴對 JVM 有了更深刻的理解了。

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

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

相關文章

是誰還沒玩AI擴圖?快跟上節奏啦

最近,抖音上的AI擴圖突然火了,看完真的讓人笑掉大牙~~~ 這一熱議的話題#AI擴圖#在短視頻平臺抖音上的播放量已經突破7.8億次,而相關的討論也如同星火燎原,迅速點燃了公眾的好奇心。從“用AI擴圖…

中偉視界:皮帶跑偏、異物檢測AI算法除了礦山行業應用,還能在鋼鐵、火電、港口等行業中使用嗎?

隨著工業化的發展,皮帶輸送機已經成為各行業中不可或缺的重要設備,但是在使用過程中,由于各種原因,皮帶常常出現跑偏問題,給生產運營帶來了諸多困擾。不僅僅是礦山行業,鋼鐵、火電、港口等行業也都面臨著皮…

C語言 掃雷游戲

代碼在一個項目里完成,分成三個.c.h文件(game.c,game.h,main.c) 在Clion軟件中通過運行調試。 /大概想法/ 主函數main.c里是大框架(菜單,掃雷棋盤初始化,隨機函數生成雷,玩家掃雷) game.h函數聲明(除main函數和游戲函數外的一些函數聲明) ga…

RepidJson將內容寫入文件

使用 RapidJSON 將內容寫入文件的步驟如下: 創建一個 rapidjson::Document 對象,將需要寫入文件的內容存儲到其中。創建一個 rapidjson::StringBuffer 對象來保存 JSON 字符串。將 rapidjson::Document 對象轉換為 JSON 字符串,并將其放入 r…

日志打印傳值 傳引用 右值引用性能測試

結論 ubuntu x86平臺qnx平臺優化傳值都是比傳引用的差 但是差距很小 測試代碼 #include <cstdint> #include <ctime> #include <string>#ifdef __linux__#define ITERATIONS 10000000 #else#define ITERATIONS 100000 #endiftemplate <typename... AR…

rust高級 異步編程 一 future

文章目錄 Async 編程簡介async/.await 簡單入門 Future 執行器與任務調度Future 特征使用 Waker 來喚醒任務構建一個定時器執行器 Executor構建執行器 完整代碼 Async 編程簡介 OS 線程, 它最簡單&#xff0c;也無需改變任何編程模型(業務/代碼邏輯)&#xff0c;因此非常適合作…

Linux設置root初始密碼

目錄 一、Linux系統中普通用戶和特權用戶&#xff08;root&#xff09; 二、Linux系統中設置root初始密碼 一、Linux系統中普通用戶和特權用戶&#xff08;root&#xff09; windows 系統中有普通用戶和特權用戶&#xff0c;特權用戶是 administer&#xff0c;普通用戶可以…

mybatisplus調用oracle存儲過程

mybatisplus調用oracle存儲過程 創建一個測試的oracle存儲過程 -- 創建攜帶返回值存儲過程 CREATE OR REPLACE PROCEDURE SP_SUM_PROC_2023(number1 IN NUMBER, number2 IN NUMBER, result OUT NUMBER,result2 OUT NUMBER) is BEGIN result : number1 number2; result2 : 99…

微服務01

筆記&#xff1a; day03-微服務01 - 飛書云文檔 (feishu.cn) 數據庫連接不上&#xff1f; 要在虛擬機啟動MySQL容器。docker start mysql 服務治理 服務提供者&#xff1a;暴露服務接口&#xff0c;供其他服務調用 服務消費者&#xff1a;調用其他服務提供的接口 注冊中心&…

Java IO流(一) 基本知識

Java IO流 一、基礎知識 IO流即存儲和讀取數據的解決方案。 &#xff08;一&#xff09;File 表示系統中的文件或者文件夾的路徑 獲取文件信息(大小&#xff0c;文件名&#xff0c;修改時間) 創建文件/文件夾 刪除文件/文件夾 判斷文件的類型 注意&#xff1a;File類只能對…

STL(五)(queue篇)

我發現之前一版在電腦上看 常用函數部分 沒有問題,由于是手打上去的,在手機上看會發生錯位問題,現已將電腦原版 常用函數部分 截圖改為圖片形式,不會再發生錯位問題,非常感謝大家的支持 ### priority_queue優先隊列出現頻率非常高,尤為重要(是一定要掌握的數據結構) 1.queue隊…

A : DS靜態查找之順序查找

Description 給出一個隊列和要查找的數值&#xff0c;找出數值在隊列中的位置&#xff0c;隊列位置從1開始 要求使用帶哨兵的順序查找算法 Input 第一行輸入n&#xff0c;表示隊列有n個數據 第二行輸入n個數據&#xff0c;都是正整數&#xff0c;用空格隔開 第三行輸入t&…

Spring-retry失敗重試機制

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、引入依賴二、主啟動類上加EnableRetry三、Server層注意 四、失敗后回調方法總結 前言 提示&#xff1a;SpringBoot項目為例 原文鏈接&#xff1a;https://…

docker全解

docker全解 一、docker的基本概念 什么是docker? docker是一個開源的應用容器引擎&#xff0c;讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中&#xff0c;然后發布到任何流行的Linux或Windows機器上&#xff0c;也可以實現虛擬化。容器是完全使用沙箱機制&#…

MIT線性代數筆記-第26講-對稱矩陣及正定性

目錄 26.對稱矩陣及正定性打賞 26.對稱矩陣及正定性 實對稱矩陣的特征值均為實數&#xff0c;并且一定存在一組兩兩正交的特征向量 這對于單位矩陣顯然成立 證明特征值均為實數&#xff1a; ? ???設一個對稱矩陣 A A A&#xff0c;對于 A x ? λ x ? A \vec{x} \lambda…

作業12.8

1. 使用手動連接&#xff0c;將登錄框中的取消按鈕使用qt4版本的連接到自定義的槽函數中&#xff0c;在自定義的槽函數中調用關閉函數。將登錄按鈕使用qt5版本的連接到自定義的槽函數中&#xff0c;在槽函數中判斷ui界面上輸入的賬號是否為"admin"&#xff0c;密碼是…

Matlab simulink PLL學習筆記

本文學習內容&#xff1a;【官方】2022小邁步之 MATLAB助力芯片設計系列&#xff08;一&#xff09;&#xff1a;電路仿真與模數混合設計基礎_嗶哩嗶哩_bilibili 時域模型 testbench搭建 菜單欄點擊simulink 創建空白模型 點擊庫瀏覽器 在PLL里面選擇一種架構拖拽到畫布。 如…

一文理解什么是交叉熵損失函數以及它的作用

今天看一個在深度學習中很枯燥但很重要的概念——交叉熵損失函數。 作為一種損失函數&#xff0c;它的重要作用便是可以將“預測值”和“真實值(標簽)”進行對比&#xff0c;從而輸出 loss 值&#xff0c;直到 loss 值收斂&#xff0c;可以認為神經網絡模型訓練完成。 那么這…

【Java用法】Hutool樹結構工具-TreeUtil快速構建樹形結構的兩種方式 + 數據排序

Hutool樹結構工具-TreeUtil快速構建樹形結構的兩種方式 數據排序 一、業務場景二、Hutool官網樹結構工具2.1 介紹2.2 使用2.2.1 定義結構2.2.2 構建Tree2.2.3 自定義字段名 2.3 說明 三、具體的使用場景3.1 實現的效果3.2 業務代碼3.3 實現自定義字段的排序 四、踩過的坑4.1 坑…

策略產品經理常用的ChatGPT通用提示詞模板

產品策略&#xff1a;請幫助我制定一個策略產品的產品策略。 市場調研&#xff1a;如何進行策略產品的市場調研&#xff1f; 競爭分析&#xff1a;如何進行策略產品的競爭分析&#xff1f; 用戶畫像&#xff1a;如何構建策略產品的用戶畫像&#xff1f; 產品定位&#xff1…