最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JVM中有哪些內(nèi)存區(qū)域及其作用

 更新時間:2019年07月15日 08:28:40   作者:正號先生  
這篇文章主要介紹了JVM中有哪些內(nèi)存區(qū)域,分別是用來干什么的,vm內(nèi)又是如何劃分內(nèi)存的呢?這個內(nèi)被加載到了那一塊內(nèi)存中?,需要的朋友可以參考下

前言

之前我們探討過一個.class文件是如何被加載到j(luò)vm中的。但是jvm內(nèi)又是如何劃分內(nèi)存的呢?這個內(nèi)被加載到了那一塊內(nèi)存中?jvm內(nèi)存劃分也是面試當(dāng)中必被問到的一個面試題。

什么是jvm內(nèi)存區(qū)域劃分?

其實這個問題非常簡單,JVM在運行我們寫好的代碼時,他是必須使用多塊內(nèi)存空間的,不同的內(nèi)存空間用來放不同的數(shù)據(jù),然后配合我們寫的代碼流程,才能讓我們的系統(tǒng)運行起來。

舉個最簡單的例子,比如咱們現(xiàn)在知道了JVM會加載類到內(nèi)存里來供后續(xù)運行,那么我問問大家,這些類加載到內(nèi)存以后,放到哪兒去了呢?想過這個問題嗎?

所以JVM里就必須有一塊內(nèi)存區(qū)域,用來存放我們寫的那些類。

包括我們定義的成員變量,類變量,方法,局部變量等等,都在jvm內(nèi)存中對應(yīng)著一塊內(nèi)存來記錄存儲。

存放類的方法區(qū)

在JDK1.8之前的版本里,代表JVM的一塊區(qū)域。在1.8版本以后,這塊區(qū)域的名字改了,叫做“Matespace”,可以認(rèn)為是“元數(shù)據(jù)空間”這樣的意思,當(dāng)然這里主要存放的還是我們自己寫的各種類的相關(guān)信息。

舉個栗子。有如下兩個類,People類沒有成員變量,而Student類有一個name的類變量。

public class Student{
  private static String name = "lisi";
}

public class People{
  public static void main(){
    Student student = new Student();
  }
}

這兩個類被加載到JVM,就會存放在這個方法區(qū)里面(注意:如果讀過我之前的章節(jié),就會明白這里的加載代表的是:加載->驗證->準(zhǔn)備->解析->初始化,類的所有類變量都會被賦值)。

執(zhí)行代碼指令的程序計數(shù)器

我們知道,被加載到j(luò)vm的類對象是我們寫的.java文件被編譯之后的.class文件。

在編譯過后會將我們的代碼編譯成計算機能讀懂的字節(jié)碼。而這個.calss文件就是,就是我們代碼編譯好的字節(jié)碼了。

加載到內(nèi)存以后,字節(jié)碼執(zhí)行引擎就開始工作了。去執(zhí)行我們編譯出來的代碼指令,如下圖

此時問題來了,我們是不是需要一塊內(nèi)存空間來記錄我們字節(jié)碼執(zhí)行引擎目前執(zhí)行到了哪行代碼?這一塊特殊的內(nèi)存區(qū)域就是“程序計數(shù)器”

這個程序計數(shù)器就是用來記錄當(dāng)前執(zhí)行的字節(jié)碼指令的位置。

如下圖:

到這里我相信會有人產(chǎn)生疑惑,就按照當(dāng)前的代碼順序執(zhí)行就行了,為什么要記錄執(zhí)行到哪里了?

因為我們寫好的代碼可能會開啟多個線程并發(fā)的執(zhí)行不同的代碼??赡墚?dāng)前線程這段代碼還沒有執(zhí)行完畢,就上下文切換到另一段代碼中。

當(dāng)線程再次上下文切換到之前的代碼時,就需要一個專門記錄當(dāng)前線程執(zhí)行到了哪一條字節(jié)碼。所以,每一個線程都有這自己的程序計數(shù)器。

如下圖:

java虛擬機棧

java代碼在執(zhí)行的時候,一定是某個線程來執(zhí)行某個方法中的代碼。

當(dāng)線程執(zhí)行到某個方法的時候,如果這個方法有局部變量,那么就需要一塊區(qū)域來存放局部變量的數(shù)據(jù)信息。這個區(qū)域就叫做java虛擬機棧。

每一個線程都有一個自己的java虛擬機棧,比如說當(dāng)執(zhí)行main方法的時候就會有一個main線程,用來存放main方法中定義的局部變量

public static void main(){
  People people = new People();
  int i = 9;
}

比如上面的main()方法中,其實就有一個"people"的局部變量,他是引用一個People的實例對象的,這個對象我們先不管他。然后有一個"i"的局部變量。

如下圖:

我想大家應(yīng)該都知道棧的數(shù)據(jù)結(jié)構(gòu),后進先出。當(dāng)方法執(zhí)行完畢以后,這個棧楨就會出棧,里面的局部變量信息就會從內(nèi)存刪除。所以局部變量是線程安全的。因為只有當(dāng)前線程能獲取到這個值。

為什么要用后進先出的數(shù)據(jù)結(jié)構(gòu)?

假設(shè)a方法當(dāng)中同步調(diào)用b方法,此時a方法的棧楨先入棧,然后再是b方法的棧楨入棧。b方法執(zhí)行完畢后,b方法的棧楨出棧,繼續(xù)執(zhí)行a方法。所以使用一個后進先出的棧結(jié)構(gòu)是非常完美的。

此時jvm的內(nèi)存模型圖如下:

java堆內(nèi)存

這一塊內(nèi)存是非常非常重要的。

我們實例化的所有對象都是存放在這個內(nèi)存中。這個實例化的對象里面會包含一些數(shù)據(jù),我們用上面的代碼來做栗子。

public class Student{
  private String name = "lisi";
  public String getNmae(){
    return name;
  }
}

public class People{
  public static void main(){
    Student student = new Student();
    student.getName();
  }
}

還是這個代碼,當(dāng)main線程執(zhí)行main()方法的時候,首先在堆內(nèi)存中實例化Student對象,然后在局部變量中創(chuàng)建student,student存的是實例化Student對象的內(nèi)存地址。然后執(zhí)行Student對象的getName()方法。

如下圖:

由上圖可以看出來,??臻g是封閉的,是線程安全的,而堆內(nèi)存中是我們主要發(fā)生線程不安全的地方,因為堆內(nèi)存的空間所有的線程其實都是能共享的。

此時jvm的內(nèi)存劃分的最終模型為:

其他內(nèi)存區(qū)域

很多java程序猿對這一塊區(qū)域的接觸是非常少的。

其實在JDK的很多底層代碼API中,比如NIO。

如果你去看源碼會發(fā)現(xiàn)很多地方的代碼不是java寫的,而是走的native方法去調(diào)用本地操作系統(tǒng)里面的一些方法,可能調(diào)用的都是c語言寫的方法。

比如說:public native int hashCode();

在調(diào)用這種native方法的時候,就會有線程對應(yīng)的本地方法棧,這個其實類似于java虛擬機棧。也是存放各種native方法的局部變量表之類的信息。

還有一塊區(qū)域,是不是jvm的,通過NIO中的allocateDirect這種API,可以在jva堆外分配內(nèi)存空間,然后通過java虛擬機棧里的DirectByteBuffer來引用和操作堆外內(nèi)存空間。

總結(jié)

基本上jvm的核心內(nèi)存區(qū)域的功能都解釋清楚了,面試能回答到這一個地步應(yīng)該也能順利通過了。

我們需要重點關(guān)注的是方法區(qū),程序計數(shù)器,java虛擬機棧和java堆內(nèi)存這些內(nèi)存區(qū)域的作用。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺談spring和spring MVC的區(qū)別與關(guān)系

    淺談spring和spring MVC的區(qū)別與關(guān)系

    下面小編就為大家?guī)硪黄獪\談spring和spring MVC的區(qū)別與關(guān)系。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • IDEA如何一鍵部署SpringBoot項目到服務(wù)器

    IDEA如何一鍵部署SpringBoot項目到服務(wù)器

    文章介紹了如何在IDEA中部署SpringBoot項目到服務(wù)器,使用AlibabaCloudToolkit插件進行配置部署,步驟包括設(shè)置服務(wù)名稱、選擇文件上傳類型、選擇jar文件、添加服務(wù)器信息、輸入上傳路徑、選擇上傳后執(zhí)行的腳本以及執(zhí)行前的操作命令
    2024-12-12
  • Springboot?引入?Redis?并配置序列化并封裝RedisTemplate?

    Springboot?引入?Redis?并配置序列化并封裝RedisTemplate?

    這篇文章主要介紹了Springboot?引入?Redis?并配置序列化并封裝RedisTemplate。文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • 基于Java實現(xiàn)五子棋小游戲(附源碼)

    基于Java實現(xiàn)五子棋小游戲(附源碼)

    這篇文章主要為大家介紹了如何通過Java實現(xiàn)簡單的五子棋游戲,文中的示例代碼講解詳細,對我們學(xué)習(xí)Java游戲開發(fā)有一定幫助,需要的可以參考一下
    2022-11-11
  • SpringCloud?hystrix斷路器與局部降級全面介紹

    SpringCloud?hystrix斷路器與局部降級全面介紹

    什么是服務(wù)降級?當(dāng)服務(wù)器壓力劇增的情況下,根據(jù)實際業(yè)務(wù)情況及流量,對一些服務(wù)和頁面有策略的不處理或換種簡單的方式處理,從而釋放服務(wù)器資源以保證核心交易正常運作或高效運作
    2022-10-10
  • Maven pom.xml文件中build,plugin標(biāo)簽的使用小結(jié)

    Maven pom.xml文件中build,plugin標(biāo)簽的使用小結(jié)

    本文主要介紹了Maven pom.xml文件中build,plugin標(biāo)簽的使用小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • SpringBoot底層注解詳解

    SpringBoot底層注解詳解

    這篇文章主要介紹了SpringBoot底層注解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2023-05-05
  • Java實現(xiàn)快速排序過程分析

    Java實現(xiàn)快速排序過程分析

    今天小編就為大家分享一篇關(guān)于Java實現(xiàn)快速排序過程分析,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Java?String類和StringBuffer類的區(qū)別介紹

    Java?String類和StringBuffer類的區(qū)別介紹

    這篇文章主要介紹了Java?String類和StringBuffer類的區(qū)別,?關(guān)于java的字符串處理我們一般使用String類和StringBuffer類有什么不同呢,下面我們一起來看看詳細介紹吧
    2022-03-03
  • Java引用傳遞和值傳遞棧內(nèi)存與堆內(nèi)存的指向操作

    Java引用傳遞和值傳遞棧內(nèi)存與堆內(nèi)存的指向操作

    這篇文章主要介紹了Java引用傳遞和值傳遞棧內(nèi)存與堆內(nèi)存的指向操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評論

于都县| 横峰县| 伊金霍洛旗| 宜黄县| 黄平县| 隆子县| 南江县| 砚山县| 海兴县| 宜宾县| 新闻| 鄱阳县| 高雄县| 平潭县| 凤山市| 东丰县| 红原县| 宜君县| 华安县| 福鼎市| 增城市| 贡嘎县| 武清区| 喀喇沁旗| 灵山县| 沂水县| 家居| 高清| 佳木斯市| 嘉峪关市| 班戈县| 南漳县| 遂宁市| 九台市| 平罗县| 行唐县| 固原市| 江阴市| 荆门市| 古田县| 塔河县|