java面試知識總結(jié)--jvm相關(guān)(模型部分)

目標

為啥面試總愛問jvm的內(nèi)存結(jié)構(gòu)呢?更有甚者,還直接jmm,拽英文???實際工作又很少用到,憑啥總問我會不會呢?不過你問了,這里我就先來答下,哈哈。
本節(jié)主要內(nèi)容,了解jvm內(nèi)存模型,類加載,線程模型

內(nèi)存模型

我喜歡按圖說話:


jvm.jpg

分析下:

  1. java文件,通過java源碼編譯器我被翻譯層class形式
  2. 我變成class形式后,包含三部分
    • 結(jié)構(gòu)信息:我的版本、各部分數(shù)量大小
    • 元數(shù)據(jù):常量、方法名、類信息等
    • 方法信息: 語句、表達式、字節(jié)碼、值棧信息
      這時候我就等待java進程工作時來找我了.

可以通過javap -c看下內(nèi)容

public class HelloWorld extends BaseResponseDTO {

    private static final int _1M = 1024 * 1024;

    private   volatile Integer integer=2;

    private  Boolean t=true;

    public static void main(String[] args) throws InterruptedException {

        HelloWorld H=new HelloWorld();
        H.integer=+1;
        H.t=false;
    }
}

對應的class文件內(nèi)容如下

public class com.yeepay.power.common.aop.HelloWorld extends com.yeepay.power.common.dto.BaseResponseDTO {
  public com.yeepay.power.common.aop.HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method com/yeepay/power/common/dto/BaseResponseDTO."<init>":()V
       4: aload_0
       5: iconst_2
       6: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       9: putfield      #3                  // Field integer:Ljava/lang/Integer;
      12: aload_0
      13: iconst_1
      14: invokestatic  #4                  // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
      17: putfield      #5                  // Field t:Ljava/lang/Boolean;
      20: return

  public static void main(java.lang.String[]) throws java.lang.InterruptedException;
    Code:
       0: new           #6                  // class com/yeepay/power/common/aop/HelloWorld
       3: dup
       4: invokespecial #7                  // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: iconst_1
      10: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      13: putfield      #3                  // Field integer:Ljava/lang/Integer;
      16: aload_1
      17: iconst_0
      18: invokestatic  #4                  // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
      21: putfield      #5                  // Field t:Ljava/lang/Boolean;
      24: return
}
  1. java進行開始執(zhí)行,首先bootstrap先加載java等核心jar包,然后是ExtensionClassLoder加載java需要的擴展包,最后appClassLoader來加載剛才生成的class文件
    這里有個概念叫做雙親委派模型
    雙親委派模型工作過程是:如果一個類加載器收到類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器完成。每個類加載器都是如此,只有當父加載器在自己的搜索范圍內(nèi)找不到指定的類時(即ClassNotFoundException),子加載器才會嘗試自己去加載。
  1. 加載完所有class,我的服務也起來了,這個時候,有用戶開始訪問我了.這時候又涉及到了jmm模型問題,看我的圖中可以看出,我所創(chuàng)建的類信息、對象數(shù)據(jù)等都存在jvm的主內(nèi)存中(當然jdk8中元數(shù)據(jù)是放到系統(tǒng)內(nèi)存中的),我在處理用戶數(shù)據(jù)時,首先要申請一個線程,讓一個線程來處理用戶工作.

  2. 我就是那個線程,我的工作生活是這樣子的(可參考文章https://mp.weixin.qq.com/s/dAHaWLiqjkuc8UpoeF6e5A,寫的不錯),我要工作,所以我向jvm申請了1m的工作空間(工作內(nèi)存,可通過-xss配置),看下我的日常工作流:

    線程工作流

哈哈,我是有家的孩子,我的壽命很長哦!

  1. 對于我的工作空間,是這樣子的:


    圖片來源網(wǎng)絡

線程的working memory只是cpu的寄存器和高速緩存的抽象描述.cpu在計算的時候,并不總是從內(nèi)存讀取數(shù)據(jù),它的數(shù)據(jù)讀取順序優(yōu)先級 是:寄存器-高速緩存-內(nèi)存。線程耗費的是CPU,線程計算的時候,原始的數(shù)據(jù)來自內(nèi)存,在計算過程中,有些數(shù)據(jù)可能被頻繁讀取,這些數(shù)據(jù)被存儲在寄存器 和高速緩存中,當線程計算完后,這些緩存的數(shù)據(jù)在適當?shù)臅r候應該寫回內(nèi)存。

所以java內(nèi)存模型分為主內(nèi)存,和工作內(nèi)存。主內(nèi)存是所有的線程所共享的,工作內(nèi)存是每個線程自己有一個,不是共享的。

每條線程還有自己的工作內(nèi)存,線程的工作內(nèi)存中保存了被該線程使用到的變量的主內(nèi)存副本拷貝。線程對變量的所有操作(讀取、賦值),都必須在工作內(nèi)存中進行,而不能直接讀寫主內(nèi)存中的變量。不同線程之間也無法直接訪問對方工作內(nèi)存中的變量,線程間變量值的傳遞均需要通過主內(nèi)存來完成,線程、主內(nèi)存、工作內(nèi)存三者之間的交互關(guān)系如下圖:

圖片來源網(wǎng)絡

每個線程通過JLS定義的八個對主存的操作指令:lock,unlock,read,load,use,assign,store,write。這些行為是不可分解的原子操作

參考資料:
https://www.cnblogs.com/wade-luffy/p/6051384.html
https://www.cnblogs.com/wxd0108/p/5479442.html
https://www.cnblogs.com/chihirotan/p/6486436.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、運行時數(shù)據(jù)區(qū)域 Java虛擬機管理的內(nèi)存包括幾個運行時數(shù)據(jù)內(nèi)存:方法區(qū)、虛擬機棧、本地方法棧、堆、程序計數(shù)器,...
    luhanlin閱讀 615評論 0 0
  • 一、運行時數(shù)據(jù)區(qū)域 Java虛擬機管理的內(nèi)存包括幾個運行時數(shù)據(jù)內(nèi)存:方法區(qū)、虛擬機棧、本地方法棧、堆、程序計數(shù)器,...
    加油小杜閱讀 1,589評論 1 15
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,689評論 1 32
  • 在一個方法內(nèi)部定義的變量都存儲在棧中,當這個函數(shù)運行結(jié)束后,其對應的棧就會被回收,此時,在其方法體中定義的變量將不...
    Y了個J閱讀 4,585評論 1 14
  • 冬天再冷,也有春來的時候。假期再長,也有結(jié)束的時候。近日偶遇寒潮,一定抵不住春潮涌動。一蓬衰草,春風一過,...
    楊無涯閱讀 444評論 0 1

友情鏈接更多精彩內(nèi)容