1 Java記憶體區域管理

来源:https://www.cnblogs.com/knowledgeispower/archive/2022/09/17/16703466.html
-Advertisement-
Play Games

1 關於自動記憶體管理 Java是由jvm來管理記憶體,包括自動分配以及自動回收,因此它不容易出現記憶體泄漏和記憶體溢出問題。 C/C++,由程式員手動管理記憶體,手動完成:使用前申請記憶體,使用後釋放記憶體。 2 運行時數據區域 Java虛擬機在執行Java程式的過程中會把它所管理的記憶體劃分為若幹個不同的數據區 ...


目錄

1 關於自動記憶體管理

  1. Java是由jvm來管理記憶體,包括自動分配以及自動回收,因此它不容易出現記憶體泄漏和記憶體溢出問題。
  2. C/C++,由程式員手動管理記憶體,手動完成:使用前申請記憶體,使用後釋放記憶體。

2 運行時數據區域

Java虛擬機在執行Java程式的過程中會把它所管理的記憶體劃分為若幹個不同的數據區域。這些區域有各自的用途,以及創建和銷毀的時間。
Java虛擬機所管理的記憶體 包括以下幾個運行時數據區域:

2.1 程式計數器

  1. 程式計數器(Program Counter Register):存儲當前線程所執行的位元組碼指令的記憶體地址。位元組碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的位元組碼指令。【通過PC來尋找下一條要執行的指令】。
  2. 程式計數器是線程私有的。cpu通過輪流分配時間片來執行線程,為了線程切換後能恢復到正確的執行位置,顯然每個線程都需要有一個獨立的程式計數器
  3. 如果線程正在執行的是一個Java方法,PC記錄的是正在執行的位元組碼指令的地址;如果正在執行的是本地(Native)方法,這個計數器值則應為空。【todo 為什麼本地方法時為空】

2.2 虛擬機棧

  1. 虛擬機棧描述的是Java方法執行的線程記憶體模型:每個方法被執行的時候,jvm會同步創建一個棧幀[後續章節詳解](Stack Frame)用於存儲局部變數表、操作數棧、動態連接、方法出口等信息
  2. 虛擬機棧也是線程私有的,它的生命周期與線程相同。

2.2.1 局部變數表

JDK8之前,對jvm記憶體的認知只停留在:堆記憶體(Heap)和棧記憶體(Stack),而“棧”通常就是指這裡講的虛擬機棧,或者更多的情況下只是指虛擬機棧中局部變數表部分。
  1. 局部變數表存儲:基本數據類型(八種:boolean、byte、char、short、int、 float、long、double)、對象引用(可能是一個指向對象起始 地址的引用指針)和returnAddress 類型(指向了一條位元組碼指令的地址)。
  2. 局部變數表所需的記憶體空間在編譯期間完成分配,當進入一個方法時,這個方法需要在棧幀中分配多大的局部變數空間是完全確定 的,在方法運行期間不會改變局部變數表的大小。【這裡的大小僅值變數槽的數量】
  3. 局部變數表以局部變數槽(Slot)來存儲數據,其中64位長度的long和 double類型的數據會占用兩個變數槽,其餘的數據類型只占用一個。(通常一個槽占據N個位元組,N大小由不同的虛擬機實現決定)。

關於棧的記憶體數據分析,在後續章節中會有更深入分析,在本節中這裡僅引入概念。

2.2.2 操作數棧

關於方法調用時的進棧跟出棧的原理,在《深入理解電腦系統》系列筆記的後續章節中會進行總結。

2.3 本地方法棧

  1. 本地方法棧(Native Method Stacks)與虛擬機棧作用是非常相似的,其區別隻是虛擬機棧為虛擬機執行Java方法(也就是位元組碼)服務,而本地方法棧則是為虛擬機使用到的本地(Native) 方法服務
  2. 線程私有的。

2.4 堆

  1. Java堆(Java Heap)存儲對象的實例
  2. Java堆是線程共用的,且比較大的一塊記憶體區域,在虛擬機啟動時創建
  3. Java堆既可以被實現成固定大小的,也可以是可擴展的,不過當前主流的Java虛擬機都是按照可擴展來實現的(通過參數-Xmx和-Xms設定)。
  4. 可彈性伸縮,但不會超過設定的最大容量,如果在Java堆中沒有記憶體完成實例分配,並且堆也無法再 擴展時,Java虛擬機將會拋出OutOfMemoryError異常
  5. Java堆可以處於物理上不連續的記憶體空間中,但在邏輯上它應該 被視為連續的。

2.5 方法區

  1. 方法區存儲已被虛擬機載入的class的類型信息、常量、靜態變數、即時編譯器編譯後的代碼緩存等數據。
  2. 方法區是線程共用
  3. 方法區不需要連續的記憶體、可以選擇固定大小或者可擴展,甚至還可以選擇不實現垃圾收集(因為這部分記憶體通常不滿足回收條件)
  4. 方法區無法滿足新的記憶體分配需求時,將拋出 OutOfMemoryError異常。

2.5.1 運行時常量池

  1. 存放編譯期生成的各種字面量與符號引用
  2. 運行時常量池(Runtime Constant Pool)是方法區的一部分

3 直接記憶體

  1. 首先,直接記憶體(Direct Memory)並不是虛擬機運行時數據區的一部分,也不是《Java虛擬機規範》中 定義的記憶體區域
  2. 它可能導致OutOfMemoryError異常出現,有必要瞭解。
在JDK 1.4中新加入了NIO(New Input/Output)類,引入了一種基於通道(Channel)與緩衝區 (Buffer)的I/O方式,它可以使用Native函數庫直接分配堆外記憶體,然後通過一個存儲在Java堆裡面的 DirectByteBuffer對象作為這塊記憶體的引用進行操作。這樣能在一些場景中顯著提高性能,因為避免了 在Java堆和Native堆中來回覆制數據。

顯然,本機直接記憶體的分配不會受到Java堆大小的限制,但是,既然是記憶體,則肯定還是會受到 本機總記憶體(包括物理記憶體、SWAP分區或者分頁文件)大小以及處理器定址空間的限制,一般服務 器管理員配置虛擬機參數時,會根據實際記憶體去設置-Xmx等參數信息,但經常忽略掉直接記憶體,使得 各個記憶體區域總和大於物理記憶體限制(包括物理的和操作系統級的限制),從而導致動態擴展時出現 OutOfMemoryError異常。

關於記憶體的深入瞭解,在《深入理解電腦系統》系列筆記的後續章節中會進行總結。

4 總結

Java記憶體區域及其數據類別概覽:


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

-Advertisement-
Play Games
更多相關文章
  • 自定義模塊 為什麼要模塊?模塊化源代碼能給我們帶來什麼好處? 試想一個巨無霸網購平臺,在沒有模塊化的情況下,如果出現bug,程式員就要在幾百萬行代碼里調試,導致後期維護成本上升,為瞭解決問題,模塊化按功能切分,把大問題轉換成小問題,讓每個模塊獨立運營,通過介面對外開放,讓程式統一調用,降低程式出錯的 ...
  • 在講到new關鍵字的執行過程之前,有幾個關於構造函數和對象之間的關係和構造函數的特點需要重點掌握: ###1.構造函數和對象的關係和區別: 構造函數:構造函數抽象了對象的公共的屬性和方法,封裝到了函數裡面,它泛指的是某一大類; 對象:通過new函數創建對象,也稱為對象藉助構造函數完成的對象實例化。 ...
  • 蒼穹之邊,浩瀚之摯,眰恦之美; 悟心悟性,善始善終,惟善惟道! —— 朝槿《朝槿兮年說》 寫在開頭 在Java領域中, 尤其是在併發編程領域,對於多線程併發執行一直有兩大核心問題:同步和互斥。其中: 互斥(Mutual Exclusion):一個公共資源同一時刻只能被一個進程或線程使用,多個進程或線 ...
  • 我的Go併發之旅。本節介紹併發的基礎知識,上下文、原語、競爭條件、原子性、記憶體訪問同步、死鎖、併發與並行、併發哲學。 ...
  • 目錄 一.前言 1.WebGL 2.OpenCV 3.Direct3D 4.OpenGL 5.OpenGL ES 和 OpenGL 二.OpenGL ES 跨平臺 1.OpenGL ES 2.Metal 3.Vulkan 三.OpenGL ES 使用場景 四.OpenGL/OpenGL ES/Web ...
  • 推導步驟1:在img標簽的src屬性里放上驗證碼的請求路徑 補充1.img的src屬性: 1.圖片路徑 2.url 3.圖片的二進位數據 補充2:字體樣式 我們電腦上之所以可以輸出各種各樣的字體樣式,其內部其實對應的是一個個以.ttf結尾的文件 由於img的src屬性里可以放圖片的二進位數據,因此 ...
  • 類的定義 面向過程 :是一種以過程為中心的編程思想,實現功能的每一步,都是自己實現的 面向對象 :是一種以對象為中心的編程思想,通過指揮對象實現具體的功能 類的理解 類是對現實生活中一類具有共同屬性和行為的事物的抽象 類是對象的數據類型,類是具有相同屬性和行為的一組對象的集合 簡單理解:類就是對現實 ...
  • 字元串: 註意:字元串是不能修改的,它不像列表一樣,可以修改其中某個元素, 所有對字元串修改操作其實都是相當於生成了一份新數據。就是copy一份改的 字元串常用操作: 註意:字元串是不能修改的,它不像列表一樣,可以修改其中某個元素, 所有對字元串修改操作其實都是相當於生成了一份新數據。就是copy一 ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...