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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

深入理解jvm虚拟机笔记

發布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解jvm虚拟机笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java內存區域與內存溢出異常

運行時數據區域

程序計數器

  • 概念: 程序計數器是一塊較小的內存空間,可以看做是當前線程所執行的字節碼的行號指示器,字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,它是程序控制流的指示器,分支,循環,跳轉,異常處理,線程恢復等基礎功能都需要依賴這個計數器來完成
  • 程序計數器是唯一一個沒有任何OutOfMemory的區域

Java虛擬機棧

  • 概念: 虛擬機棧描述的是Java方法執行的線程內存模型:每個方法被執行的時候,Java虛擬機都會同步創建一個棧幀(Stack Frame)用于存儲局部變量表,操作數棧,動態連接,方法出口等信息.每一個方法被調用直至執行完畢的過程,就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程
  • 局部變量表: 存放了編譯期可知的各種Java虛擬機基本數據類型(八種),對象引用,returnAddress類型(指向一條字節碼指令的地址)
  • 對象引用:不等同于對象本身,可能是一個指向對象起始地址的引用指針,也可能是一個指向一個代表對象句柄或者其他于此對象相關的位置
  • 局部變量表中的基本數據類型以局部變量槽(Slot)表示,其中64位長度的long和double數據會占用兩個變量槽,其余類型占用一個

本地方法棧

  • 本地方法棧與虛擬機棧發揮的作用是非常相似的,其區別只是虛擬機棧為java方法服務,本地方法棧為本地方法服務

Java堆

  • Java堆是被所有線程共享的一塊內存區域,在虛擬機啟動時創建,此內存區域的唯一目的就是存放對象實例,幾乎所有對象實例都在這里分配內存
  • 根據《Java虛擬機規范》中規定,Java堆可以處于物理上不連續的內存空間中,但在邏輯上它應該被視為連續的,但對于大對象(如數組),多數虛擬機實現處于實現簡單,存儲高效的考慮,很可能會要求連續的內存空間

方法區

  • 方法區也是線程共享的內存區域,它用于存儲已被虛擬機加載的類型信息,常量,靜態變量,即時編譯器編譯后的代碼緩存等數據

運行時常量池

  • 運行時常量池是方法區的一部分,Class文件中除了有類的版本,字段,方法,接口等描述信息外,還有一項信息是常量池表,用于存放編譯期生成的各種字面量與符號引用,這部分內容將在類加載后存放到方法區的運行時常量池中

HotSpot虛擬機對象探秘

對象的創建

-創建對象的幾種方式: new 復制 反序列化 反射

  • 當虛擬機遇到一條字節碼new指令時,首先檢查指令參數是否能在常量池中定位到一個類的符號引用,檢查這個符號引用代表的類是否已被加載 解析 和初始化過,如果沒有先執行類加載過程
  • 類加載檢查通過后,虛擬機將為新生對象分配內存,對象所需的內存大小在類加載完成后便可完全確定
  • 對象分配空間任務
    • 將一塊確定大小的內存塊從Java堆中劃分出來,假設Java對中內存是絕對規整的,所有被使用過的內存放在一邊,空閑的內存放在另一邊,中間放著一個指針作為分界點的指示器
    • 分配內存就僅僅是把指針向空閑方向挪動一段與對象大小相等的距離,這種分配方式稱為"指針碰撞"
    • 如果Java堆中內存并不是規整的,已被使用的內存和空閑的內存相互交錯在一起,沒有辦法進行指針碰撞
    • 虛擬機就必須維護一個列表,記錄哪些內存塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的記錄,這種分配方式稱為"空閑列表"
    • Java堆是否規整又所才用的垃圾收集器是否帶有空間壓縮整理的能力決定
  • 對象的內存布局

    對象在堆內存中存儲可以劃分為三部分: 對象頭,實例數據和對齊填充

    • 對象頭包括兩類信息:第一類是用于存儲對象自身的運行時數據,如哈希碼,GC分代年齡,鎖狀態標志,線程持有的鎖,偏向鎖ID,偏向時間戳等,這一部分官方稱為"MarkWord"; 另一部分是類型指針,指向它的元數據的指針,Java虛擬機通過這個指針來確定對象是哪個類的實例 ; 如果對象是一個Java數組,那么還需要記錄數組對象的長度
    • 實例數據: 對象真正存儲的有效信息,即程序代碼中所定義的各種類型的字段內容,無論是從父類繼承還是在子類中定義的字段都必須記錄起來
    • 對齊填充: 此部分并不是必然存在的,也沒有任何特別的含義,僅僅起著占位符的作用.在Hotspot虛擬機中,要求對象起始地址必須是8字節的整數倍,如果對象實例部分數據沒有對齊,則需要通過對齊填充來補全

    對象的訪問定位

    由于reference類型在《Java虛擬機規范》里只規定了它是一個指向對象的引用,并沒有定義這個引用應該通過什么方式去定位,訪問到堆中對象的具體位置,所以目前有兩種的主流訪問方式 :句柄和直接指針

    • 句柄: 使用句柄訪問,在Java堆中則會劃分出一塊內存作為句柄池,reference中存儲的就是對象的句柄地址,而句柄中包含了對象實例數據和類型數據各自具體的地址信息(Hotspot主要采用直接指針,如果采用shenandoah收集器會有一次額外轉發)
    • 直接指針: 如果使用直接指針,Java堆中對象的內存布局就必須考慮如何放置訪問類型數據的相關信息,reference中存儲的直接就是對象地址,如果只是訪問對象本身的話,不需要多一次間接訪問的開銷
    • 優點:
      • 使用句柄訪問優勢在于reference中存儲的是穩定句柄地址,在對象被移動時,只會改變句柄中的實例數據指針,而reference本身不需要被修改
      • 直接指針速度更快,節省了一次指針定位的時間開銷

    總結

    以上是生活随笔為你收集整理的深入理解jvm虚拟机笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

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