java-JVM內存區域JVM運行時內存

一. JVM 內存區域

在這里插入圖片描述

  • JVM 內存區域主要分為線程私有區域【程序計數器、虛擬機棧、本地方法區】、線程共享區域【JAVA 堆、方法區】、直接內存。
  • 線程私有數據區域生命周期與線程相同, 依賴用戶線程的啟動/結束 而 創建/銷毀(在 HotspotVM 內, 每個線程都與操作系統的本地線程直接映射, 因此這部分內存區域的存/否跟隨本地線程的生/死對應)。
  • 線程共享區域隨虛擬機的啟動/關閉而創建/銷毀。
  • 直接內存并不是 JVM 運行時數據區的一部分, 但也會被頻繁的使用: 在 JDK 1.4 引入的 NIO 提供了基于 Channel 與 Buffer 的 IO 方式, 它可以使用 Native 函數庫直接分配堆外內存, 然后使用DirectByteBuffer 對象作為這塊內存的引用進行操作(詳見: Java I/O 擴展), 這樣就避免了在 Java堆和 Native 堆中來回復制數據, 因此在一些場景中可以顯著提高性能。

1. 程序計數器(線程私有)

  • 一塊較小的內存空間, 是當前線程所執行的字節碼的行號指示器,每條線程都要有一個獨立的程序計數器,這類內存也稱為“線程私有”的內存。
  • 正在執行 java 方法的話,計數器記錄的是虛擬機字節碼指令的地址(當前指令的地址)。如果還是 Native 方法,則為空。
  • 這個內存區域是唯一一個在虛擬機中沒有規定任何 OutOfMemoryError 情況的區域。

2. 虛擬機棧(線程私有)

  • 是描述 java 方法執行的內存模型,每個方法在執行的同時都會創建一個棧幀(Stack Frame)用于存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應著一個棧幀在虛擬機棧中入棧到出棧的過程。
  • 棧幀( Frame)是用來存儲數據和部分過程結果的數據結構,同時也被用來處理動態鏈接(Dynamic Linking)、 方法返回值和異常分派( Dispatch Exception)。棧幀隨著方法調用而創建,隨著方法結束而銷毀——無論方法是正常完成還是異常完成(拋出了在方法內未被捕獲的異常)都算作方法結束。

3. 本地方法區(線程私有)

  • 本地方法區和 Java Stack 作用類似, 區別是虛擬機棧為執行 Java 方法服務, 而本地方法棧則為Native 方法服務, 如果一個 VM 實現使用 C-linkage 模型來支持 Native 調用, 那么該棧將會是一個C 棧,但 HotSpot VM 直接就把本地方法棧和虛擬機棧合二為一。

4. 堆(Heap-線程共享)-運行時數據區

  • 是被線程共享的一塊內存區域,創建的對象和數組都保存在 Java 堆內存中,也是垃圾收集器進行垃圾收集的最重要的內存區域。由于現代 VM 采用分代收集算法, 因此 Java 堆從 GC 的角度還可以細分為: 新生代(Eden 區、From Survivor 區和To Survivor 區)和老年代。

5. 方法區/永久代(線程共享)

  • 即我們常說的永久代(Permanent Generation), 用于存儲被 JVM 加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據. HotSpot VM 把 GC 分代收集擴展至方法區, 即使用 Java堆的永久代來實現方法區, 這樣 HotSpot 的垃圾收集器就可以像管理 Java 堆一樣管理這部分內存,而不必為方法區開發專門的內存管理器(永久帶的內存回收的主要目標是針對常量池的回收和類型的卸載, 因此收益一般很小)。
  • 運行時常量池(Runtime Constant Pool)是方法區的一部分。Class 文件中除了有類的版本、字段、方法、接口等描述等信息外,還有一項信息是常量池(Constant Pool Table),用于存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載后存放到方法區的運行時常量池中。 Java 虛擬機對 Class 文件的每一部分(自然也包括常量池)的格式都有嚴格的規定,每一個字節用于存儲哪種數據都必須符合規范上的要求,這樣才會被虛擬機認可、裝載和執行。

二. JVM 運行時內存

Java 堆從 GC 的角度還可以細分為: 新生代(Eden 區、From Survivor 區和To Survivor 區)和老年代。

1. 新生代

是用來存放新生的對象。一般占據堆的 1/3 空間。由于頻繁創建對象,所以新生代會頻繁觸發MinorGC 進行垃圾回收。新生代又
分為 Eden 區、ServivorFrom、ServivorTo 三個區。

1.1. Eden 區

Java 新對象的出生地(如果新創建的對象占用內存很大,則直接分配到老年代)。當 Eden 區內存不夠的時候就會觸發 MinorGC,
對新生代區進行一次垃圾回收。

1.2. ServivorFrom

上一次 GC 的幸存者,作為這一次 GC 的被掃描者。

1.3. ServivorTo

保留了一次 MinorGC 過程中的幸存者。

1.4. MinorGC 的過程(復制->清空->互換)

MinorGC 采用復制算法。
1:eden、servicorFrom復制到 ServicorTo,年齡+1
首先,把 Eden 和 ServivorFrom 區域中存活的對象復制到 ServicorTo 區域(如果有對象的年齡以及達到了老年的標準,則賦值
到老年代區),同時把這些對象的年齡+1(如果 ServicorTo 不夠位置了就放到老年區);
2:清空 eden、servicorFrom
然后,清空 Eden 和 ServicorFrom 中的對象;
3:ServicorTo和 ServicorFrom互換
最后,ServicorTo 和 ServicorFrom 互換,原 ServicorTo 成為下一次 GC 時的 ServicorFrom區。

2. 老年代

  • 主要存放應用程序中生命周期長的內存對象。
  • 老年代的對象比較穩定,所以 MajorGC 不會頻繁執行。在進行 MajorGC 前一般都先進行了一次 MinorGC,使得有新生代的對象晉身入老年代,導致空間不夠用時才觸發。當無法找到足夠大的連續空間分配給新創建的較大對象時也會提前觸發一次 MajorGC 進行垃圾回收騰出空間。MajorGC 采用標記清除算法:首先掃描一次所有老年代,標記出存活的對象,然后回收沒有標記的對象。MajorGC 的耗時比較長,因為要掃描再回收。MajorGC 會產生內存碎片,為了減少內存損耗,我們一般需要進行合并或者標記出來方便下次直接分配。當老年代也滿了裝不下的時候,就會拋出 OOM(Out of Memory)異常。

3. 永久代

  • 指內存的永久保存區域,主要存放 Class 和 Meta(元數據)的信息,Class 在被加載的時候被放入永久區域,它和和存放實例的區域不同,GC 不會在主程序運行期對永久區域進行清理。所以這也導致了永久代的區域會隨著加載的 Class 的增多而脹滿,最終拋出 OOM 異常。

3.1. JAVA8 與元數據

  • 在 Java8 中,永久代已經被移除,被一個稱為“元數據區”(元空間)的區域所取代。元空間的本質和永久代類似,元空間與永久代之間最大的區別在于:元空間并不在虛擬機中,而是使用本地內存。因此,默認情況下,元空間的大小僅受本地內存限制。類的元數據放入 nativememory, 字符串池和類的靜態變量放入 java 堆中,這樣可以加載多少類的元數據就不再由MaxPermSize 控制, 而由系統的實際可用空間來控制。

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

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

相關文章

SwiftUI 動畫進階:實現行星繞圓周軌道運動

0. 概覽 SwiftUI 動畫對于優秀 App 可以說是布帛菽粟。利用美妙的動畫我們不僅可以活躍界面元素,更可以單獨打造出一整套生動有機的世界,激活無限可能。 如上圖所示,我們用動畫粗略實現了一個小太陽系:8大行星圍繞太陽旋轉,而衛星們圍繞各個行星旋轉。 在本篇博文中,您將…

vue3實現防抖、單頁面引入、全局引入、全局掛載

文章目錄 代碼實現單頁面引入全局引入使用 代碼實現 const debounce (fn: any, delay: number) > {let timer: any undefined;return (item: any) > {if (timer) clearTimeout(timer);timer setTimeout(() > fn(item), delay);} };export default debounce;單頁面…

Python + Selenium 處理瀏覽器Cookie

工作中遇到這么一個場景:自動化測試登錄的時候需要輸入動態驗證碼,由于某些原因,需要從一個已登錄的機器上,復制cookie過來,到自動化這邊繞過登錄。 瀏覽器的F12里復制出來的cookie內容是文本格式的: uui…

【第二講---初識SLAM】

SLAM簡介 視覺SLAM,主要指的是利用相機完成建圖和定位問題。如果傳感器是激光,那么就稱為激光SLAM。 定位(明白自身狀態(即位置))建圖(了解外在環境)。 視覺SLAM中使用的相機與常見…

VB+SQL銀行設備管理系統設計與實現

摘要 隨著銀行卡的普及,很多地方安裝了大量的存款機、取款機和POS機等銀行自助設備。銀行設備管理系統可以有效的記錄銀行設備的安裝和使用情況,規范對自助設備的管理,從而為用戶提供更加穩定和優質的服務。 本文介紹了銀行設備管理系統的設計和開發過程,詳細闡述了整個應…

Flink之Task解析

Flink之Task解析 對Flink的Task進行解析前,我們首先要清楚幾個角色TaskManager、Slot、Task、Subtask、TaskChain分別是什么 角色注釋TaskManager在Flink中TaskManager就是一個管理task的進程,每個節點只有一個TaskManagerSlotSlot就是TaskManager中的槽位,一個TaskManager中可…

數據結構單鏈表

單鏈表 1 鏈表的概念及結構 概念:鏈表是一種物理存儲結構上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈 接次序實現的 。 在我們開始講鏈表之前,我們是寫了順序表,順序表就是類似一個數組的東西&#xff0…

上海虛擬展廳制作平臺怎么選,蛙色3DVR 助力行業發展

引言: 在數字化時代,虛擬展廳成為了企業宣傳的重要手段。而作為一家位于上海的實力平臺,上海蛙色3DVR憑借其卓越的功能和創新的技術,成為了企業展示和宣傳的首選。 一、虛擬展廳的優勢 虛擬展廳的崛起是指隨著科技的進步&#x…

36_windows環境debug Nginx 源碼-使用 VSCode 和WSL

文章目錄 配置 WSL編譯 NginxVSCode 安裝插件launch.json配置 WSL sudo apt-get -y install gcc cmake sudo apt-get -y install pcre sudo apt-get -y install libpcre3 libpcre3-dev sudo apt-get

手機商城網站的分析與設計(論文+源碼)_kaic

目錄 摘 要 1 1 緒論 2 1.1選題背景意義 2 1.2國內外研究現狀 2 1.2.1國內研究現狀 2 1.2.2國外研究現狀 3 1.3研究內容 3 2 網上手機商城網站相關技術 4 2.1.NET框架 4 2.2Access數據庫 4 2.3 JavaScript技術 4 3網上手機商城網站分析與設…

Grafana+Prometheus技術文檔-進階使用-監控spring-boot項目

阿丹: 之前已經實現了使用Prometheus來對服務器進行了監控和儀表盤的創建,現在就需要對這些監控方法使用在spring-boot中去。 實現思路: 1、集成Actuator 2、加入Prometheus的依賴 3、配置開放端口、以及開放監控 4、配置Prometheus中的配置…

一次網絡不通“爭吵“引發的思考

作者: 鄭明泉、余凱 為啥爭吵,吵什么? “你到底在說什么啊,我K8s的ecs節點要訪問clb的地址不通和本地網卡有什么關系…” 氣憤語氣都從電話那頭傳了過來,這時電話兩端都沉默了。過了好一會傳來地鐵小姐姐甜美的播報聲…

iview默認樣式覆蓋

scoped 屬性是 HTML5 中的新屬性。 當style標簽擁有scoped屬性時,它的css樣式只能用于當前的Vue組件,可以使組件的樣式不相互污染。 如果一個項目的所有style標簽都加上了scoped屬性,相當于實現了樣式的模塊化。 1、全頁面覆蓋 不添加scoped…

【一】ubuntu20.04上搭建containerd版( 1.2.4 以上)k8s及kuboard V3

k8s 部署全程在超級用戶下進行 sudo su本文請根據大綱順序閱讀! 一、配置基礎環境(在全部節點執行) 1、安裝docker 使用apt安裝containerd 新版k8s已經棄用docker轉為containerd,如果要將docker改為containerd詳見&#xff1a…

對dubbo的DubboReference.check的參數進行剖析

背景 在使用dubbo的時候,發現當消費者啟動的時候,如果提供者沒有啟動,即使提供者后來啟動了,消費者也調不通提供者提供的接口了。 注冊中心使用都是nacos dubbo版本是3.0.4 例子 接口 public interface DemoService {String…

“深入解析JVM內部機制:探秘Java虛擬機的奧秘“

標題:深入解析JVM內部機制:探秘Java虛擬機的奧秘 摘要:本文將深入解析JVM(Java虛擬機)的內部機制,從字節碼執行到垃圾回收,逐步揭示Java程序運行的奧秘。通過理論分析和示例代碼,讀…

thinkphp5.1 trace 不顯示sql語句

config/app.php app_debug > true,//線上環境為 false // 應用Trace app_trace > true,//線上環境為 false config/database.php debug > true, config/log.php close > false, thinkphp5.1x 設計非常奇怪 必須開啟…

使用dockerfile手動構建JDK11鏡像運行容器并校驗

Docker官方維護鏡像的公共倉庫網站 Docker Hub 國內無法訪問了,大部分鏡像無法下載,準備逐步構建自己的鏡像庫。【轉載aliyun官方-容器鏡像服務 ACR】Docker常見問題 阿里云容器鏡像服務ACR(Alibaba Cloud Container Registry)是面…

內網穿透-外遠程連接中的RabbitMQ服務

文章目錄 前言1.安裝erlang 語言2.安裝rabbitMQ3. 內網穿透3.1 安裝cpolar內網穿透(支持一鍵自動安裝腳本)3.2 創建HTTP隧道 4. 公網遠程連接5.固定公網TCP地址5.1 保留一個固定的公網TCP端口地址5.2 配置固定公網TCP端口地址 前言 RabbitMQ是一個在 AMQP(高級消息隊列協議)基…

Linux:shell腳本:基礎使用(4)《正則表達式-grep工具》

正則表達式定義: 使用單個字符串來描述,匹配一系列符合某個句法規則的字符串 正則表達式的組成: 普通字符串: 大小寫字母,數字,標點符號及一些其他符號 元字符:在正則表達式中具有特殊意義的專用字符 正則表…