【JAVA進階架構師指南】之二:JVM篇

来源:https://www.cnblogs.com/wukongbubai/archive/2020/03/21/12536309.html
-Advertisement-
Play Games

前言 談到JAVA,就不得不提JVM JAVA程式員繞不開的話題.也許有童鞋會說,我不懂JVM,但是我一樣可以寫出JAVA代碼,我相信說這種話的童鞋,往往是只有1 3年的初級開發人員,對JAVA理解還不深,不明白JVM的重要性,那接下來我們來說說,為什麼要學習JVM? 1.理解JVM,才能幫助我們寫 ...


前言

  談到JAVA,就不得不提JVM---JAVA程式員繞不開的話題.也許有童鞋會說,我不懂JVM,但是我一樣可以寫出JAVA代碼,我相信說這種話的童鞋,往往是只有1-3年的初級開發人員,對JAVA理解還不深,不明白JVM的重要性,那接下來我們來說說,為什麼要學習JVM?
  1.理解JVM,才能幫助我們寫出更好,更健壯的代碼.舉個例子,以下代碼的執行結果會是什麼呢?很多童鞋肯定會說:嗯?當我傻嗎?兩個不都是true嗎?這有啥好說的,真的是這樣嗎?感興趣的童鞋可以自己下來試一試,至於為什麼是這樣的結果,在下文會解釋清楚.
file
  2.理解JVM,可以幫助我們提升JAVA程式的性能,排除問題.
  3.也是最重要的一點,面試必問!

虛擬機的種類

  我們知道,目前使用範圍最廣的虛擬機是sun公司的HotSpot VM,在這之前,sun公司發佈的第一款虛擬機是Sun Classic/Exact VM,這是世界上第一款商用虛擬機.另外其他公司也有自己的虛擬機,比如IBM J9 VM,Google Android Dalvik VM,Apache Harmony,Microsoft VM等待,但是使用範圍最廣的還是HotSpot.

JVM記憶體劃分

  引用一張圖來說明:
file

  可以看到,JVM主要由方法區/堆區/虛擬機棧/本地方法棧/程式計數器五個部分組成,從線程的角度來看,分為線程公有的部分(方發區/java堆)和線程私有的部分(虛擬機棧/本地方法棧/程式計數器).

方法區

  存放已經被虛擬機載入的[類信息/常量/靜態變數/即時編譯後的代碼]等,有些文章也稱方法區為永久代,主要發生的異常是記憶體溢出:OutOfMemoryError.另外在JDK1.6版本中,常量池(這裡特指運行時常量池,我們一般說的常量池也都是指的運行時常量池)是存放於方法區中的(因此方法區可能會經常記憶體溢出),JDK1.7的時候常量池移到了JAVA堆(Heap)中,在JDK1.8的時候,已經沒有方法區了,取而代之的是一塊叫元數據(metaSpace)的空間.

java堆

  java堆主要存放的是對象實例以及數組等信息,主要發生的異常仍然是記憶體溢出:OutOfMemoryError.並且java堆區是GC重點關註的區域.另外,我們常說,幾乎所有的對象分配記憶體都是在java堆中進行,而不是說所有對象100%都在java堆中分配記憶體,是因為有兩種例外情況不會在java堆中分配記憶體,第一種是TLAB(線程本機分配緩存),另一種是棧上分配,既然想成為一名架構師,童鞋們應該要弄明白什麼是TLAB和棧上分配,發揮你們的能力,盡情Google吧.

虛擬機棧

  java方法執行的記憶體模型,每個方法在執行的時候會封裝成一個棧幀,存放[局部變數表/操作數棧/動態鏈表/方法出口]等信息,方法的執行對應棧幀入棧和出棧的過程.棧的深度是有大小的,預設情況下棧的記憶體為1M,因此虛擬機棧除了發生記憶體溢出異常,還有可能發生StackOverFlowError異常.

本機方法棧

  和虛擬機棧作用類似,區別在於本地方法棧保存的是native方法的信息.

程式計數器

  當前線程執行的位元組碼行號指示器,是JVM中唯一一塊沒有記憶體溢出異常的區域.

常量池

  接下來我們再倒回來看看,文章開頭的代碼,執行結果會是什麼:
file
  127返回的是true,128返回的確是false.為什麼?
  首先我們知道,在java語言中 == 比較的是兩個對象的記憶體地址,只有equals方法才是比較兩個對象是否相等,執行結果告訴我們,值都為127的Integer a和b記憶體地址是相同的,他們是同一個對象,而值為128的Integer c和d的記憶體地址不同,他們是不同的兩個對象,那為什麼127就是相同的對象,128就是不同的對象呢?還記得上文中,我們說方法區中有一塊區域叫運行時常量池,存放的是各種常量,java語言對byte/short/char/int/string設置了常量池,比如我們查看Integer的源碼:
file
  可以發現,Integer的常量池範圍是-128~127,在該範圍內的Integer對象都會復用常量池中的值,因此a和b是相同對象,而超過該範圍,會重新new一個新的對象,因此c和d都是重新new出來的,地址當然不同,因此是false.另外String類型的常量池和前面四種類型不一樣,String類型的常量池是通過final來實現的.而float/double沒有常量池的概念,因為float和double本身都是科學技術法表示近似數,無法精確計算,存在精度丟失的情況,因此沒法為float和double創建常量池.

  本文我們瞭解了JVM的記憶體區域,下一篇文章,讓我們來學習類載入機制,敬請期待!

  如果覺得博主寫的不錯,歡迎關註博主微信公眾號,博主會不定期分享技術乾貨!
  file

本文由博客一文多發平臺 OpenWrite 發佈!


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

-Advertisement-
Play Games
更多相關文章
  • 上回用typescript實現了單例模式,這回來實現工廠模式。工廠模式又分為簡單工廠模式、工廠方法模式以及抽象工廠模式。 ...
  • [toc] 模型驅動設計的構造塊 非原創,感謝《領域驅動設計》這本書 為了保證軟體實現得簡潔並且與模型保持一致,不管實際情況如何複雜,必須運用建模和設計的最佳實踐。領域驅動設計改變了某些傳統觀念的側重點。某些設計決策能夠使模型和程式緊密結合在一起,互相促進對方的效用。這種結合要求我們註意每個元素的細 ...
  • 測試是任何軟體開發項目中最重要的步驟之一。如果跳過此過程,則結果可能是災難性的。 ...
  • 我一直有用微信讀書閱讀的習慣,最近發現微信閱讀還有網頁版。登陸微信閱讀的網頁版,需要我們用App掃碼進行登陸。如下麵的界面所示: 使用你的微信閱讀App掃描完上面的二維碼並點擊確認登陸後,網頁版就能自動登陸。登陸後會展示你的閱讀記錄,書架信息等。 我突然很好奇,這個掃碼登陸到底是怎麼實現的,所以就去 ...
  • 首先下載好軟體,鏈接在這裡 鏈接:https://pan.baidu.com/s/1op-W-ZX1tqefHffs3m-r0A 提取碼:0jwm 這裡麵包含了Rational Rose 2007版的可視化建模軟體,也包含了破解文件,直接下載就可以了。 我在網上按照其他人的按照過程中出現了安裝之後打 ...
  • [toc] 領域驅動設計 運用領域模型 綁定模型和實現 聰明的項目組成員花費了幾個月的時間進行仔細的研究並且開發出了詳盡的領域模型(類圖)。然而對類圖研究不能讓我深入地瞭解該應用程式的代碼和設計,這讓我備感困擾。當開發人員開始實現應用程式時,他們很快就發現,儘管分析人員說得頭頭是道,他們依然無法將這 ...
  • [toc] 運用領域模型 交流與語言的使用 非原創,感謝《領域驅動設計》這本書 領域模型可成為軟體項目通用語言的核心。該模型是一組得自於項目人員頭腦中的概念,以及反映了領域深層含義的術語和關係。這些術語和相互關係提供了模型語言的語義,雖然語言是為領域量身定製的,但就技術開發而言,其依然足夠精確。正是 ...
  • [toc] 運用領域模型 消化知識 非原創,感謝《領域驅動設計》這本書 有效建模的要素 (1) 模型和實現的綁定。最初的原型雖然簡陋,但它在模型與實現之間建立了早期鏈接,而且在所有後續的迭代中我們一直在維護該鏈接。 (2) 建立了一種基於模型的語言。隨著項目的進展,雙方都能夠直接使用模型中的術語,並 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...