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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

jvm内存模型_JVM内存模型的相关概念

發布時間:2025/3/11 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jvm内存模型_JVM内存模型的相关概念 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.前言


Android的虛擬機是根據移動設備的特點基于Java虛擬機(JVM)改進而來,雖然沒有保留規范,但作為Java語言的使用者,了解一下JVM的規范還是有必要的。

2.JVM內存模型


JVM在執行Java程序時,會把它管理的內存劃分為若干個的區域,每個區域都有自己的用途和創建銷毀時間。如下圖所示,可以分為兩大部分,線程私有區和共享區:

Memory.png

2.1.線程私有區
  • 程序計數器。當同時進行的線程數超過CPU數或其內核數時,就要通過時間片輪詢分派CPU的時間資源,不免發生線程切換。這時,每個線程就需要一個屬于自己的計數器來記錄下一條要運行的指令。如果將是Java方法,則記錄執行的字節碼地址;是本地方法,則計數器為空。

  • 虛擬機棧,與線程同時創建。每個方法執行時都會創建一個棧幀來存儲方法的信息,新調用的方法入棧,返回的出棧,所以棧的大小決定方法調用的可達深度。若需要的棧深度大于可用深度時,則StackOverflowError;若棧進行擴展,但內存不夠時,OutOfMemoryError。

  • 本地方法棧,與虛擬機棧作用相似。但它不是為Java方法服務的,而是本地方法(C語言)。由于規范對這塊沒有強制要求,不同虛擬機實現方法不同。

2.2.線程共享區

此區域是用來存儲被各線程共享的數據的。

  • 方法區,用于存放加載類的元數據信息,如常量、靜態變量和即時編譯器編譯后的代碼。若要分代,算是永久代,以前類大多“static”的,很少被卸載或收集,現回收廢棄常量和無用的類。其中運行時常量池存放編譯生成的各種常量。

  • 堆,存放對象實例和數組,是垃圾回收的主要區域,分為新生代和老年代。剛創建的對象在新生代的Eden區中,經過GC后進入新生代的S0區中,再經過GC進入新生代的S1區中,15次GC后仍存在就進入老年代。這是按照一種回收機制進行劃分的,不是固定的。若堆的空間不夠實例分配,則OutOfMemoryError。

2.3.注意事項

棧是運行時單位,代表著邏輯,內含基本數據類型和堆中對象引用,所在區域連續,沒有碎片;堆是存儲單位,代表著數據,可被多個棧共享(包括成員中基本數據類型、引用和引用對象),所在區域不連續,會有碎片。

3.垃圾回收


我們都知道調用 System.gc() 方法只是通知系統去回收,是否回收不能確定。

3.1.回收的判斷

JVM中,將一個對象真正回收需經歷兩次標記過程,每次都是先判斷對象有沒有被持有引用,再判斷對象是否必要執行 finalize() 方法。

  • 持有判斷。最先使用是引用計數算法,當對象有一個引用,即增加一個計數;刪除一個引用,即減少一個計數。計數為零的對象,判斷為不可用,但是無法處理循環引用的問題。現主流的都是可達性分析算法,通過將一系列稱為GC Roots的對象作為起始點,開始向下搜索,走過的路徑則是引用鏈。若所有GC Roots都與某對象無引用鏈相連,即不可達時,判斷為不可用。
    注意:GC Roots對象包括:虛擬機棧(棧幀中的本地變量表)中引用對象;方法區中類靜態屬性引用的對象;方法區中常量池引用的對象;本地方法棧(一般的本地方法,即JNI)中引用的對象。

  • 必要判斷。當對象沒有重寫 finalize() 方法或者 finalize() 方法已被虛擬機調用過,都將視為“沒有必要執行”。否則此對象將放置在F-Queue的隊列中,由一個虛擬機自動建立的、低優先級的Finalizer線程去觸發該方法,但不承諾等待它運行結束,以防執行緩慢或為死循環,導致隊列其它對象永久等待,乃至內存回收系統崩潰。

  • 對F-Queue中對象進行二次標記。只要有對象重新與GC Roots對象關聯,就會被移出隊列,否則GC回收。

3.2.垃圾收集算法

當確定哪些垃圾可以被回收后,需要做的就是高效地進行垃圾回收。由于JVM沒有給出明確的規定,各廠商實現方式不同,這里只討論常見垃圾收集算法的核心思想。

  • 標記-清除算法,最基礎的算法,分為兩個階段。標記階段:標出所有需要被回收的對象;清除階段:回收被標記對象所占用的空間。容易產生大量內存碎片,導致無足夠空間分配給大對象,從而提前觸發垃圾收集動作。

  • 復制算法,為了解決標記-清除算法的缺陷。將可用內存按容量分為大小相等的兩塊,每次只使用其中的一塊。當一塊用完時,復制可用對象至另一塊并清除自己的內存空間,從而避免出現內存碎片。可用內存為實際的一半,利用率低;且當存活對象很多時,效率也會降低。

  • 標記-整理算法,吸取以上兩種算法優點。標記階段與標記-清除算法同階段一致,整理階段則將存活對象移向一端,再清理邊界以外空間。

  • 分代收集算法,目前主流。根據對象存活的生命周期,將內存劃分為兩大區域。老年代:每次垃圾收集只有少量對象需回收,一般采用標記-整理算法;新生代:每次垃圾收集都有大量對象需回收,大部分采用復制算法。但空間上不是等大的兩塊,而是一塊大的Eden區域,兩塊小的Survivor區域,每次只使用一大一小兩區域。垃圾回收時,它們將內部存活對象都移至空閑的小區域并清理自己。

3.3.垃圾收集器

垃圾收集算法是理論,而垃圾收集器是實現。下面根據海子的文章列出HotSpot(JDK 7)提供的幾種垃圾收集器。

  • Serial/Serial Old 收集器是最基本最古老的收集器,它是一個單線程收集器,并且在它進行垃圾收集時,必須暫停所有用戶線程。Serial收集器是針對新生代的收集器,采用的是Copying算法;Serial Old收集器是針對老年代的收集器,采用的是Mark-Compact算法。它的優點是實現簡單高效,但是缺點是會給用戶帶來停頓。

  • ParNew 收集器是Serial收集器的多線程版本,使用多個線程進行垃圾收集。

  • Parallel Scavenge/Parallel Old 收集器是多線程(并行)收集器。Parallel Scavenge收集器是針對新生代的收集器,它在回收期間不需要暫停其他用戶線程,其采用的是Copying算法,該收集器與前兩個收集器有所不同,它主要是為了達到一個可控的吞吐量;Parallel Old收集器是針對老年代的收集器,使用多線程和Mark-Compact算法。

  • CMS(Current Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器,它是一種并發收集器,采用的是Mark-Sweep算法。

  • G1收集器是當今收集器技術發展最前沿的成果,它是一款面向服務端應用的收集器,它能充分利用多CPU、多核環境。因此它是一款并行與并發收集器,并且它能建立可預測的停頓時間模型。

4.內存分配


內存分配主要是在堆上分配,由于涉及到分配時某區域空間不足等問題,需結合垃圾收集器和JVM相關參數,所以規則不是固定的。

5.總結

到這里,基本上可以在寫代碼時大致知道對象的內存情況,所以一定要注意避免內存泄露及其導致的內存溢出問題。

總結

以上是生活随笔為你收集整理的jvm内存模型_JVM内存模型的相关概念的全部內容,希望文章能夠幫你解決所遇到的問題。

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