Java - JVM內存區域的劃分

Java 程序運行時,需要在內存中分配空間。為了提高運算效率,就對空間進行了不同區域的劃分,因為每一片區域都有特定的處理數據方式和內存管理方式。

分配:通過關鍵字new創建對象分配內存空間,對象存在堆中。
釋放 :對象的釋放是由垃圾回收機制決定和執行的

JVM的內存可分為3個區:

堆(heap)
棧(stack)
方法區(method,也叫靜態區)

?

堆區: 程序員自己申請,運行時線程公有

通過new生成的對象都存放在堆中,對于堆中的對象生命周期的管理由Java虛擬機的垃圾回收機制GC進行回收和統一管理


jvm只有一個堆區(heap),且被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身和數組本身;
優點是可以動態分配內存大小,缺點是由于動態分配內存導致存取速度慢。

虛擬機棧: 系統自己分配,運行時線程私有

棧內存主要是存放一些基本類型的變量和對象的引用變量。最典型的就是我們new一個對象時,對象名作為變量就存放在棧內存中


棧內存有一個很重要的特殊性——在棧中的數據可以共享(已存在的值不會再次創建)
int a = 3;
int b = 3;
(編譯器先處理int a =3;首先它會在棧中創建一個變量為a的引用,然后查找棧中是否有3這個值,如果沒找到,就將3存放進來,然后將a指向3。接著處理int b)


每個方法執行的同時都會創建一個棧幀(Stack Frame)用于存儲局部變量表、操作數棧、動態鏈接、方法出口等。局部變量表存放了編譯器可知的各種基本數據類型、對象引用和returnAddress類型


每個方法從調用直至完成的過程,都對應著一個棧幀從入棧到出棧的過程。每當一個方法執行完成時,該棧幀就會彈出棧幀的元素作為這個方法的返回值,并且清除這個棧幀,Java棧的棧頂的棧幀就是當前正在執行的活動棧,也就是當前正在執行的方法,方法的調用過程也是由棧幀切換來產生結果。


在JVM規范中,對這個區域規定了兩種異常情況:
1.如果線程請求的棧深度大于虛擬機允許的深度,將拋出StackOverflowError異常;
2.如果虛擬機棧可以動態擴展,在擴展時無法申請到足夠的內存,就會拋出OutOfMemoryError異常。

本地方法棧:


和虛擬機棧所發揮的作用基本一致,不同的是:

虛擬機棧為虛擬機執行Java方法(字節碼)服務
本地方法棧則為虛擬機使用到的Native方法服務
本地方法棧也會拋出StackOverflowError和OutOfMemoryError異常。

方法區(靜態區):

是各個線程共享的內存區域,它用于存儲class二進制文件,包含所有的class和static變量,包含了虛擬機加載的類信息、常量(常量池)、靜態變量(靜態域)、即時編譯后的代碼等數據。


方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變量。


被所有的線程共享,方法區包含所有的class(class是指類的原始代碼,要創建一個類的對象,首先要把該類的代碼加載到方法區中,并且初始化)和static變量。

常量池:在編譯期間就將一部分數據存放于該區域,包含以final修飾的基本數據類型的常量值、String字符串。(在java6時它是方法區的一部分;1.7又把他放到了堆內存中;1.8之后出現了元空間,它又回到了方法區。)


靜態域:存放類中以static聲明的靜態成員變量。

程序計數器:當前線程所執行的行號指示器。通過改變計數器的值來確定下一條指令,比如循環,分支,跳轉,異常處理,線程恢復等都是依賴計數器來完成。
程序計數器:
一個非常小的內存空間,用來保存程序執行到的位置(線程私有),它可以看作是當前線程所執行的字節碼的行號指示器。

Metaspace元空間:

在JDK1.8中,永久代已經不存在,存儲的類信息、編譯后的代碼數據等已經移動到了MetaSpace(元空間)中,元空間并沒有處于堆內存上,而是直接占用的本地內存(NativeMemory)。
元空間的本質和永久代類似,都是對JVM規范中方法區的實現。
元空間與永久代之間最大的區別在于:元空間并不在虛擬機中,而是使用本地內存。
元空間的大小僅受本地內存限制,可以指定元空間大小。


Java8為什么要將永久代替換成Metaspace?
1、字符串存在永久代中,容易出現性能問題和內存溢出。
2、類及方法的信息等比較難確定其大小,因此對于永久代的大小指定比較困難,太小容易出現永久代溢出,太大則容易導致老年代溢出。
3、永久代會為 GC 帶來不必要的復雜度,并且回收效率偏低。
4、Oracle 可能會將HotSpot 與 JRockit 合二為一。

?基本數據類型

int a = 3;
int b = 3;

編譯器先處理 int a = 3;首先它會在棧中創建一個變量為 a 的引用,然后查找有沒有字面值為3的地址,沒找到,就開辟一個存放3這個字面值的地址,然后將 a 指向3的地址。

接著處理 int b = 3;在創建完 b 這個引用變量后,由于在棧中已經有3這個字面值,便將 b 直接指向3的地址。這樣,就出現了 a 與 b 同時均指向3的情況。

對象

public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

一個類通過使用new運算符可以創建多個不同的對象實例,這些對象實例將在堆中被分配不同的內存空間,改變其中一個對象的狀態不會影響其他對象的狀態:

? ? ? ? Person one = new Person("小明",15);Person two = new Person("小王",17);

在堆內存中只創建了一個對象實例,在棧內存中創建了兩個對象引用,兩個對象引用同時指向一個對象實例。

? ? ? ? Person one = new Person("小明",15);Person two = one;

數組
數組是一種引用類型,數組用來存儲同一種數據類型的數據。

一旦初始化完成,即所占的空間就已固定下來,即使某個元素被清空,但其所在空間仍然保留,因此數組長度將不能被改變。

int[] array = new int[5]

首先會在棧中創建引用變量,在堆中開辟5個int型數據的空間,該引用變量存放數組首地址,即實現數組名來引用數組。

?

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

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

相關文章

柔性數組詳解

前言:柔性數組是C99中新添加的概念,它是結構體里面的最后一個成員,因為它的大小未知,所以很靈活,稱之為柔 1 柔性數組占不占結構體的空間呢? 不占 typedef struct Stu {char y;int x;int arr[];//有些編譯器…

數據在內存中的存儲(整型篇)

1.辨析原碼反碼補碼: 1.原碼:有32位(int類四個字節,一個字節八個比特位),第一位是符號位,0正1負,其余為二進制位。 2.計算一般是對原碼進行計算,但在負數計算使用原碼會導…

強化學習(二)——Dueling Network(DQN改進)

與DNQ相比,使用優勢函數(A函數)和狀態價值函數(V)代替之前的Q(動作價值)函數, 最核心公式為 Q ? ( s , a ) A ? ( s , a ) V ? ( s ) ? max ? a A ? ( s , a ) Q^*(s,a)A^*(s,a)V^*(s)-\max_a A^*(s,a) Q?(s,a)A?(s,a)V…

高效利用內存資源之動態內存管理詳解

目錄 一、為什么存在動態內存分配 二、動態內存函數的介紹 2.1malloc 2.2free 2.3calloc 2.4realloc 三、常見的動態內存錯誤 3.1對NULL指針的解引用操作 3.2對動態開辟空間的越界訪問 3.3對非動態開辟內存使用free釋放 3.4使用free釋放一塊動態開辟內存的一部分 3.…

Spring Boot 3 集成 Druid 連接池詳解

在現代的Java應用中,使用一個高效可靠的數據源是至關重要的。Druid連接池作為一款強大的數據庫連接池,提供了豐富的監控和管理功能,成為很多Java項目的首選。本文將詳細介紹如何在Spring Boot 3項目中配置數據源,集成Druid連接池&…

【ACM獨立出版、確定的ISBN號】第三屆密碼學、網絡安全和通信技術國際會議(CNSCT 2024)

第三屆密碼學、網絡安全和通信技術國際會議(CNSCT 2024) 2024 3rd International Conference on Cryptography, Network Security and Communication Technology 隨著互聯網和網絡應用的不斷發展,網絡安全在計算機科學中的地位越來越重要&…

Android Kotlin 泛型:強大的類型抽象和重用利器

一、什么是泛型? 泛型是一種參數化類型的機制,它允許我們在定義類、接口和方法時使用類型參數,從而實現代碼的重用和類型安全。通過使用泛型,我們可以將類型作為參數傳遞給類或方法,在不同的場景中實現靈活的類型適配…

精選:免費且高效的郵件營銷軟件推薦

好用的郵件營銷軟件可以幫助企業獲取客戶、維系客戶關系。對于有想做郵件營銷想法,但是想先試試的企業來講,免費版郵件營銷軟件就是個不錯的選擇。當然,免費的郵件郵件營銷軟件雖然在價格上有極大的優勢,但是功能上會有各種限制。…

Java生態系統最受歡迎的工具類使用指南 ?

???? 博主貓頭虎(????)帶您 Go to New World??? ?? 博客首頁——????貓頭虎的博客?? ?? 《面試題大全專欄》 ?? 文章圖文并茂??生動形象??簡單易學!歡迎大家來踩踩~?? ?? 《IDEA開發秘籍專欄》 ?? 學會IDEA常用操作,工作效率翻倍~?? ?…

【小白專用】MySQL查詢數據庫所有表名及表結構其注釋

一、先了解下INFORMATION_SCHEMA 1、在MySQL中,把INFORMATION_SCHEMA看作是一個數據庫,確切說是信息數據庫。其中保存著關于MySQL服務器所維護的所有其他數據庫的信息。如數據庫名,數據庫的表,表欄的數據類型與訪問權 限等。在INF…

網絡安全——SSH密碼攻擊實驗

一、實驗目的要求: 二、實驗設備與環境: 三、實驗原理: 四、實驗步驟:? 五、實驗現象、結果記錄及整理: 六、分析討論與思考題解答: 一、實驗目的要求: 1、了解SSH密碼攻擊、FTP密碼攻擊…

【BEV感知 EA-LSS 方案】Edge-aware Lift-splat-shot

前言 本文分享LSS方案的改進方案——EA-LSS,它解決了“深度跳變”問題,提出了一個新框架Edge-aware Lift-splat-shot 。 適用于“多視圖轉BEV”,可以代替原來的LSS模塊,并有效地提高了檢測精度,而推理時間的增加很少。 在nuScenes測試集上驗證,純相機模型或多模態模型…

Jmeter 請求簽名api接口-BeanShell

Jmeter 請求簽名api接口-BeanShell 項目簽名說明編譯擴展jar包jmeter 使用 BeanShell 調用jar包中的簽名方法 項目簽名說明 有簽名算法的api接口本地不好測試,使用BeanShell 擴展jar 包對參數進行簽名,接口簽名算法使用 sha512Hex 算法。簽名的說明如下…

Mybatis是如何進行分頁的?

程序員的公眾號:源1024,獲取更多資料,無加密無套路! 最近整理了一份大廠面試資料《史上最全大廠面試題》,Springboot、微服務、算法、數據結構、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、數據庫等等 …

Django系列之Celery異步框架+RabbitMQ使用

在Django項目中,如何集成使用Celery框架來完成一些異步任務以及定時任務呢? 1. 安裝 pip install celery # celery框架 pip install django-celery-beat # celery定時任務使用 pip install django-celery-results # celery存儲結果使用2. Django集成…

gin投票系統3

對應視頻v1版本 1.優化登陸接口 將同步改為異步 原login前端代碼&#xff1a; <!doctype html> <html lang"en"> <head><meta charset"utf-8"><title>香香編程-投票項目</title> </head> <body> <m…

開關量防抖濾波器(梯形圖和SCL源代碼)

模擬量防抖超限報警功能塊請查看下面文章鏈接: https://rxxw-control.blog.csdn.net/article/details/133969425https://rxxw-control.blog.csdn.net/article/details/133969425 1、開關量防抖濾波器 2、防抖濾波 3、梯形圖代碼

useMemo和useCallback

useMemo和useCallback是React中的兩個優化性能的鉤子&#xff08;Hooks&#xff09;。它們都可以用來緩存計算結果&#xff0c;避免在每次渲染時都重新執行耗時的操作。然而&#xff0c;它們的主要區別在于緩存的內容和使用場景。 useMemo useMemo用于緩存那些計算成本較高的值…

2.Feign使用、上下文隔離及源碼閱讀

目錄 概述使用配置pom.xmlfeign 接口編寫controller 測試降級處理pom.xmlapplication.yml代碼 Feign如何初始化及調用源碼閱讀初始化調用 feign的上下文隔離機制源碼 結束 概述 閱讀此文&#xff0c;可以知曉 feign 使用、上下文隔離及源碼閱讀。源碼涉及兩方面&#xff1a;fe…

課后作業7.3.1:構造一個自己的小操作系統

構造一個自己的 mini 操作系統 任務描述 請實現如下功能&#xff1a; 1.寫一個命令解釋器程序 mysh.c &#xff0c;其功能是接收用戶輸入的命令并給出反饋。要求該程序既支持內部命令 cd、sync、exit &#xff1b;也支持外部命令&#xff0c;即可以接收 cat、ls 等命令&#x…