日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解JAVA虚拟机学习笔记(一)JVM内存模型

發布時間:2024/8/23 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解JAVA虚拟机学习笔记(一)JVM内存模型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘要:?? 上周末搬家后,家里的寬帶一直沒弄好,跟電信客服反映了N遍了終于約了個師傅明天早上來遷移寬帶,可以結束一個多星期沒網的痛苦日子了。這段時間也是各種忙,都一個星期沒更新博客了,再不寫之前那種狀態和激情都要慢慢褪去了,總覺得心里慌的一逼,這怎么行呢?!趁明天周末,在公司電腦上記錄下這周的一些學習內容。

? 上周末搬家后,家里的寬帶一直沒弄好,跟電信客服反映了N遍了終于約了個師傅明天早上來遷移寬帶,可以結束一個多星期沒網的痛苦日子了。這段時間也是各種忙,都一個星期沒更新博客了,再不寫之前那種狀態和激情都要慢慢褪去了,總覺得心里慌的一逼,這怎么行呢?!趁明天周末,在公司電腦上記錄下這周的一些學習內容。近期在看一本很經典的java書籍:《深入理解java虛擬機 第二版》,幾年前也翻過,但那時候功力不夠,不太能看懂就沒看了?,F在回過頭來看,發現確實寫的很好,很多知識點都能理解了,而且講的也很有深度,收獲頗多。后期計劃按照這本書的內容寫出一系列博客,來深入學習和復習下java虛擬機相關的知識。

??? ? ?一、JVM內存模型概述

? ? ? ? ? ? ??JVM內存模型其實也挺簡單的,這里先提2個知識點:

? ? ? ? ? ? ? ? ? ? 1、組成:java堆,java棧(即虛擬機棧),本地方法棧,方法區和程序計數器。

? ? ? ? ? ? ? ? ? ? 2、是否共享:其中方法區和堆區是線程共享的,虛擬機棧,本地方法棧和程序計數器是線程私有的,也稱線程隔離的,每個區域存儲不同的內容。這2個知識點必須牢記,是掌握JVM內存模型的基礎。

? ? ? ? ? ? ? ? ? ? ? ? ? ?

?? ? ? 二、程序計數器

? ? ? ? ? ? ? JVM中的程序計數器是一塊很小的內存區域,但是這塊內存區域挺有意思的。主要特性有3個:

? ? ? ? ? ? ? 1、存儲內容:對于java普通方法(即沒用native關鍵字修飾的方法),存儲的是執行過程中當前指令的地址,而對于native方法,這里是空的(undefined),為啥呢?因為調用本地方法的時候可能已經超出了JVM虛擬機的內存地址了。

? ? ? ? ? ? ? 2、線程私有的:為什么程序計數器是線程私有的?根據存儲內容也好理解,假如是線程共享的,那多個線程執行的時候,都不知道自己當前線程執行的地址是哪個了,有的線程快,有的線程慢,快的執行完就進入下一步,等慢的線程執行完回來發現自己的地址都變了,豈不亂套?

? ? ? ? ? ? ? 3、是JVM中唯一不會報內存溢出(OutOfMemoryError)的區域。

?? ? ? 三、虛擬機棧

? ? ? ? ? ? ??虛擬機棧主要存儲的是一個個棧幀,每個棧幀中存儲的是局部變量表,操作數棧,動態鏈接和方法出口信息等。其中局部變量表中存儲的是方法中定義的一些局部變量,對象的引用,參數,和方法的返回地址等。局部變量表所占用的空間大小在編譯期就能確定,在方法運行的時候,并不會改變局部變量表的空間大小,這結合局部變量表存儲的內容就很好理解。操作數棧可以理解為對當前操作的數據入出棧,對于64位長度的long和double類型,每個操作數占用2個字寬(slot),其他類型的操作數占用一個字寬(slot)。每個方法調用時都會創建一個棧幀,執行的過程對應的就是一個棧幀在虛擬機棧中從入棧到出棧的過程。有關棧幀的內容可以參考一個網友寫的一篇博客:https://blog.csdn.net/xtayfjpk/article/details/41924283,講的很好很詳細。這里放個棧幀的圖,看了一目了然。

? ? ? ? ? ??

? ? ? ? ? ?關于虛擬機棧內存溢出有2種情況:

? ? ? ? ? ?1、線程請求的棧深度 超過了虛擬機允許的深度,會拋出StackOverflowError,所以當我們在代碼中看到這個異常時,就應該想到可能是虛擬機棧出了問題。

? ? ? ? ? ?2、如果虛擬機??梢詣討B擴展(當前大部分JVM都可以動態擴展,不過JVM也允許固定長度的虛擬機棧),當擴展時無法申請到足夠的內存時,會拋出OutOfMemoryError異常。

?? ? ? 四、本地方法棧

? ? ? ? ???這塊知識點比較簡單,本地方法棧和虛擬機棧的功能類似,只不過是為JVM調用native方法時服務的,而且JVM對本地方法使用的語言(比如Java調用C語言實現的功能,就需要定義native方法來實現)、使用方式和數據結構都沒有強制規定,因此不同的虛擬機可以自由實現。而且HotSpot虛擬機直接把本地方法棧和虛擬機棧合二為一。與虛擬機棧類似,本地方法棧也會拋出StackOverflowError和OutOfMemoryError。

?? ? ? 五、方法區

? ? ? ? ? ?方法區是一個比較重要的區域,java虛擬機規范中把方法區描述為堆的一個邏輯部分,但是為了和Heap(堆區)對應,也稱Non-Heap(非堆區)。主要存儲的是靜態變量,常量(包括運行時常量),類的加載信息和java編譯后的代碼。這部分空間不需要連續,可以選擇固定大小和可擴展,通常在這部分是沒有GC的,因為GC回收的都是些靜態變量,常量和類的加載信息,這些對象回收效果通常不盡人意,因此可以選擇不實現垃圾回收。這塊區域也稱為持久代,當這塊內存不足時,也會報OutOfMemoryError異常。

?? ? ? 六、堆區

? ? ? ???Java堆區是JVM內存中最胖的一塊區域,因為這里存儲的都是對象的實例和數組對象。這塊區域是線程共享的,在JVM啟動時就會創建,想想如果這么大的空間是線程私有的,那內存不得爆掉嗎?按照java虛擬機規范,堆區的內容可以物理上不連續,只要邏輯上連續即可,在實現時可以是固定大小的,也可以是可擴展的,而且通常都是可擴展的,我們常用的內存參數-Xms和-Xmx就是用來調節堆大小的。java堆區按生命周期不同,分為新生代和老年代。新生代又可以細分為Eden和Survivor區,而Survivor又可以細分為Survivor1和Survivor2,這兩者通常只使用其中一塊,另一塊用來GC時保留存活的對象。大部分的new出來的對象都是存放在Eden區,如果是大對象,比如一個很大的數組或者List對象,可以通過JVM參數-XX:PretenureSizeThreshold將超過指定大小的對象直接存入到老年代,需要注意的是,寫程序時應該盡量避免朝生夕死的大對象進入老年代,因為相比年輕代的GC,老年代GC的成本更大。Eden和Survivor的默認大小比值的8:1:1,新生代默認的GC算法是復制算法。老年代的默認GC算法是標記整理法。關于這2種GC算法,會在下篇博客講解。

當堆中沒有足夠內存時,會拋出OutOfMemoryError異常。關于堆區的內存模型,可以參考下面的圖片:

? ? ? ?

原文鏈接?

本文為云棲社區原創內容,未經允許不得轉載。?

總結

以上是生活随笔為你收集整理的深入理解JAVA虚拟机学习笔记(一)JVM内存模型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。