淺聊JVM--基礎版

来源:https://www.cnblogs.com/kuangsun125/archive/2023/05/07/17379715.html
-Advertisement-
Play Games

淺聊JVM--基礎版 一、來源 jvm共有三種 Sun公司: HotSpot使用最多 BEA:JRockit IBM:J9VM ​ 今天我們主要瞭解的是Sun公司的HotSpot(關於HotSpot的愛恨情仇這裡就不做過多解釋了。)我們以前測試jdk是否安裝成功,java的環境變數是否配置成功會使用 ...


淺聊JVM--基礎版

一、來源


jvm共有三種

  • Sun公司: HotSpot使用最多
  • BEA:JRockit
  • IBM:J9VM

​ 今天我們主要瞭解的是Sun公司的HotSpot(關於HotSpot的愛恨情仇這裡就不做過多解釋了。)我們以前測試jdk是否安裝成功,java的環境變數是否配置成功會使用java -version命令來檢查。有一個細節大家可以看一下,cmd輸入java -version回車後,可以查看jvm。上圖

​ 大家可以看到,我們目前使用大都是Sun公司的產品。那麼jvm處於什麼位置呢?其實jvm是在操作系統之上,和硬體並無直接聯繫。

面試題:jvm、jdk、jre的區別?

二、概述


​ JVM是Java Virtual Machine的縮寫,通俗來說也就是運行Java代碼的容器。當項目啟動時,會根據jvm相關配置參數,在電腦的記憶體中開啟一片空間用於運行jvm,之後Java相關代碼就會被載入進jvm中運行。那麼為什麼Java代碼可以實現“一次編譯,到處運行”的機制應該就與jvm有關了吧。

Java作為一種高級語言,要讓電腦執行Java程式,也得需要經過編碼-->編譯-->運行步驟。但是Java編譯程式並不能將Java源代碼直接編譯為電腦能識別的0/1指令,而是編譯為位元組碼文件(.class)這時候就需要jvm將位元組碼文件翻譯為與平臺有關的0/1指令。所以有了jvm,Java程式就達到了“一次編譯到處運行”的目的。所以其跨平臺好的根本原因就是因為jvm的存在。但是JVM並不代表就可以執行class了,JVM執行.class還需要JRE下的lib類庫的支持,尤其是rt.jar。

​ 它的記憶體空間包括方法區、堆、方法棧、本地方法棧、PC寄存器。(以上5塊又成為運行時數據區)。我們剛纔也提到,Java源代碼經過Java編譯程式。能夠產生相應的.class文件,也就是位元組碼文件。位元組碼文件經過jvm中的解釋器,再次編譯成特定機器上的機器碼指令。上圖:

關於類載入器是如何工作的,大家可以參考文章:

[Java 類載入和類載入器 - 掘金 (juejin.cn)](https://juejin.cn/post/7226665757882236986)

面試題:什麼是雙親委派原則?

面試題:JNI(Java Native Interface)Java本地方法介面中Native關鍵字的作用?

我們今天主要淺聊一下PC寄存器、方法區、棧、堆

三、PC寄存器


​ 程式計數器(Program Count Register):每個線程都有一個程式計數器,它是線程私有,是用來存儲指向下一條指令的地址,也就是即將來執行的指令代碼。在執行引擎讀取下一條指令,是一個非常小的記憶體空間。(關於程式計數器更多的細節或者是在迴圈、判斷等條件下PC是如何跳轉的,大家可以參考《電腦組成原理》類資料瞭解更多底層原理。)

四、方法區


​ 方法區(Method Area):只是 JVM 規範中定義的一個概念,用於存儲被 JVM 載入的類信息、常量、靜態變數、即時編譯器編譯後的代碼等數據。具體放在哪裡,不同的實現可以放在不同的地方。HotSpot VM把 GC 分代收集擴展至方法區,即使用 Java 堆的永久代來實現方法區。(關於什麼是永久代,請向下看)

面試題:一張白紙,畫出對象實例化過程的記憶體圖?

五、棧


​ 棧(Stack):裡面放的是8大基本數據類型+對象引用+實例的方法。棧記憶體里,主管程式的運行,生命周期和線程同步,線程結束,棧記憶體也就釋放了,棧記憶體結束,程式也就結束了。

​ 我們都知道在Java中,程式員不需要顯示的去釋放一個對象的記憶體的,而是由虛擬機自行回收垃圾,那麼垃圾回收的過程不會涉及到棧(也就是說棧不存在垃圾回收的情況)

棧基於後進先出的特性,當執行完成後,會被彈出棧。

為什麼main()是先執行,最後結束?(因為一開始是main()方法最先入棧,最後彈出,結束執行)

棧溢出的問題(StackOverflow)

看下一面一段程式:

jvm中的棧為:

六、堆


​ 堆:(Heap)運行時數據區,是被線程共用的一塊記憶體區域,創建的對象和數組都保存在 Java 堆記憶體中,也是垃圾收集器進行 垃圾收集的最重要的記憶體區域。堆記憶體細分為3個區域:

  • 新生區(伊甸園去)--->Young/New(Eden Space)
  • 養老區(Old)
  • 永久區(Perm)

新生區又可以分為伊甸園區(Eden Space)、幸存0區、幸存1區,(幸存0區又可以稱為SurvivorFrom區、幸存1區可以稱為SurvivorTo區。From區和To區是可以來回動態交換的,具體什麼原因,大家可以查閱資料)

伊甸園區:所有的對象都是在伊甸園區new出來的。

幸存者(0、1)區:在伊甸園區里經過一次輕GC後活下來的進入幸存(0、1)區,被清理掉的就死亡掉。(關於GC是如何進行垃圾回收的,大家可以自行查閱資料,這裡只是簡單瞭解)

養老區:在經過多次的輕GC處理後,幸存(0,1)區也都滿了,會觸發重GC來進行清理伊甸園區和幸存(0,1)區,那麼進入養老區的就是重GC也未殺死的。若養老區也滿了,就相當於記憶體已滿,報OOM錯誤(java.lang.OutOfMemoryError:Java heap sapce)

聽聞:99%的對象都是臨時對象,能進入養老區的不多,所以OOM的錯誤也很少見。

面試題:工作中,遇到OOM了,你是怎麼排查的?

1、嘗試擴大堆記憶體空間,如果還滿,可能有垃圾代碼存在

2、分析記憶體,使用專業工具看哪裡出了問題

[面試官:工作中遇到過 OOM 嗎?你是怎麼排查的? - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/165981061)

擴大記憶體空間參數:

(具體的參數設置大家自己查閱)

例如:

永久區:這個區域常駐記憶體,用來存放JDK自身攜帶的Class對象,Interface元數據,存儲的是java運行時的一些環境或類信息,該區域不存在垃圾回收GC。關閉虛擬機就會釋放這個記憶體。

關於永久區的更新換代:

jdk1.6之前:永久代,常量池在方法區

jdk1.7:永久代,但是慢慢退化了(去永久代)常量池在堆中

jdk1.8之後:無永久代,常量池在元空間

方法區又稱非堆,本質還是堆,只是為了區分概念。

OK,結束!!!

資料參考:

狂神說Java

JVM入門筆記


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大佬們呀,花了好幾天的時間總算是看著頁面展示可以了,求賜教! 小米商城主頁,對大佬來說肯定簡單爆了,我抄寫了好久呀,總是有一點點的小問題,還搞不明白 主要是一個靜態的小米商城頁面,HTML前端代碼不複雜,一堆的div和ul、li就沒問題了,主要是css代碼搞不懂導致顯示不正常 話不多說,直接上代碼: ...
  • 前端開發中涉及表單的頁面非常多,看似功能簡單,開發快速,實則占去了很大一部分時間。當某個表單包含元素過多時還會導致html代碼過多,vue文件過大。從而不容易查找、修改和維護。為了提高開發效率及降低維護成本,下麵介紹表單配置化組件的封裝原理與封裝方法。 ...
  • 環境:CentOS 7.6_x64 FreeSWITCH版本 :1.10.9 Python版本:3.9.12 一、背景描述 PCM(Pulse Code Modulation,脈衝編碼調製)音頻數據是未經壓縮的音頻採樣數據,它是由模擬信號經過採樣、量化、編碼轉換成的標準數字音頻數據。 在FreeSW ...
  • 架構介紹 系統組件 CAS伺服器和客戶端構成了CAS系統體繫結構的兩個物理組件,它們通過各種協議進行通信。 CAS伺服器 CAS伺服器是基於Spring Framework構建的Java servlet,其主要職責是通過簽發和驗證ticket來驗證用戶並授予對啟用CAS認證了的服務(通常稱為CAS客 ...
  • pandas中用來承載數據的兩個最重要的結構分別是: Series:相當於增強版的一維數組 DataFrame:相當於增強版的二維數組 pandas最大的優勢在於處理表格類數據,如果數據維度超過二維,一般我們會使用另一個 python的庫 numpy。 本篇主要介紹這兩種核心數據結構的創建方式。 1 ...
  • 概述 由於gpt比較火爆,可以幫我們寫文章、寫代碼等,本文將製作屬於我們自己的ai助手,無需翻牆, 準備工作 在萬能的某寶購買open ai的apikey,直接搜索apikey即可找到 下載Andlua+軟體,在後臺回覆【andlua】即可獲得下載鏈接 最終效果 代碼實現 main.lua主要代碼 ...
  • 過去若幹年,一邊工作編程,一邊思考提煉,寫了一些關於“寫整潔業務代碼”的文章,在隨筆分類“代碼修行”下。有一天在公司文檔空間分享時,突然想到:可以製作一本電子書,將過往的重要經驗總結起來,也是對自己十年編程生涯的一個階段性回顧,作為繼續前進的階梯。 我的第一本電子書 書名:《代碼修行:一步一步寫出整 ...
  • 我們在項目開發中,經常會對一些參數進行校驗,比如非空校驗、長度校驗,以及定製的業務校驗規則等,如果使用if/else語句來對請求的每一個參數一一校驗,就會出現大量與業務邏輯無關的代碼,繁重不堪且繁瑣的校驗,會大大降低我們的工作效率,而且準確性也無法保證。為保證數據的正確性、完整性,前後端都需要進行數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...