<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            java語言

            java中JVM虛擬機內存模型詳細說明

            時間:2025-01-17 09:03:05 java語言 我要投稿
            • 相關推薦

            java中JVM虛擬機內存模型詳細說明

              以下是百分網小編為大家收集的java中JVM虛擬機內存模型詳細說明內容,歡迎閱讀學習!

              JVM的內部結構如下圖:

              java中JVM虛擬機內存模型詳細說明 - 天涯草 - 天涯草

              一個優秀Java程序員,必須了解Java內存模型、GC工作原理,以及如何優化GC的性能、與GC進行有限的交互,有一些應用程序對性能要求較高,例如嵌入式系統、實時系統等,只有全面提升內存的管理效率,才能提高整個應用程序的性能。

              本文將從JVM內存模型、GC工作原理,以及GC的幾個關鍵問題進行探討,從GC角度提高Java程序的性能。

              1 java內存分為:

              程序計數器(當前線程所執行字節碼的行號指示器,字節碼解釋器要通過改變這個計數器的值來選擇下一條字節碼指令,分支、循環、異常處理等。每條線程都有一條獨立的程序計數器,屬于線程私有的內存區)、

              java虛擬機棧(也是線私有的,存儲局部變量、操作棧,每個方法執行時創建一個棧幀,執行過程就是棧的出棧入棧操作)、

              本地方法棧(執行native方法)、

              年輕代堆(eden、from survivor、to survivor)、年老代堆(經過幾次垃圾回收,保存下來的)、

              持久代堆(也叫方法區,保存常量池和類型數據信息,不會被回收)、

              直接內存(使用native方法直接分配堆外內存,再通過堆內的DirectByteBuffer作為這塊內存的引用進行操作)

              2 對象訪問有兩種:通過句柄池和直接通過指針,句柄池的好處是垃圾回收后,不需要改變對象引用,只要改變句柄引用;直接指針的好處是效率較高。

              引用《深入java虛擬機第二章》

              解釋了minor gc和major gc,和兩個survivor區之于復制收集算法的意義

              3 jvm內存機制

              java內存中的四種引用解析,強引用、弱引用、軟引用、虛引用

              4 垃圾回收算法

              4.1 引用計數,效率高,但是無法解決無用對象循環引用的問題。及時引用計數大于0,但卻不可用。

              4.2 根對象可達,java虛擬機使用的方式。可以作為根對象的有:虛擬機棧幀中引用的對象,方法區中(持久區)類靜態屬性引用的對象(類靜態屬性在創建實例之前就已經為這個屬性分配好空間,創建好實例,在所有的類實例中共享),方法區中常量引用的對象(比如常量字符串),本地方法棧中引用的對象(native方法)。

              4.3 引用強度,強(即傳統理解的引用,obj=new obj()),軟(softReference,在內存溢出之前,GC會將這部分納入回收范圍,進行二次回收,如果還是沒有足夠內存,那么OOM),弱(weakReference,一旦GC進行回收,無論內存是否充足都會被回收),虛(有虛引用不會影響生命周期,無法通過虛引用來獲得一個對象,唯一作用是對象被回收時能得到一個系統通知,PhantomReference)

              4.4 對象在回收之前會調用僅有一次finalize(),可以在finalize中自救,把自己被引用。只有當對象覆蓋finalize()方法才會被放入執行finalize()的隊列。不建議使用這個,可以用try{} finally代替。

              4.5 java回收算法

              標記清除法,效率低下,會產生內存碎片。

              復制收集算法,較為主流的算法,分區,eden,survivor,將未被回收的對象移動到survivor區,然后一次性清理eden區。這種算法適用于對象存活率不高的情況,要犧牲一部分分配空間,一般來說eden:survivor=8:1。

              當對象存活率很高的時候,復制收集算法的效率會出現問題,所以有了標記-整理算法。把所有存活對象整理到一端,再把另一端直接清理掉。

              分代算法,java內存一般都分為新生代和年老代,根據兩個區域對象存活率的特點,分別采用了復制-收集算法和標記-清理(標記-整理)算法。

              4.6 垃圾收集器

              serial收集器,單線程收集。很可惡,會停掉其他用戶線程。糟糕的用戶體驗。但是適用于client端,因為產生的垃圾量少,回收快,幾十毫秒解決。

              parNew收集器,和serial一樣。區別是收集時采用多線程機制。

              CMS收集器,可以讓收集線程和用戶線程并發執行,可惜的是作為年老代的收集器,只能和上面兩個不靠譜的收集器一起配合使用。它是以最短停頓時間為目標的年老代收集器,使用mark-sweep算法(標記-清除)。回收步驟是初始標記(stop world),并發標記,重新標記(stop world),并發清除。stop world的時間很短,所以可以認為是用戶線程并發的收集器。

              parallel scavenge收集器,是并發收集器,可以和用戶線程并存。可以通過參數控制吞吐量=用戶線程時間/(用戶時間+垃圾收集時間),前臺程序適用低吞吐量,減少用戶操作每次停頓的時間;而后臺程序適用于高吞吐量,盡快完成后臺的計算。也稱作吞吐量優先收集器。該收集器還能設置自適應模式,會根據實際情況動態調整吞吐量。

              serial old收集器和serial一樣,用于年老代收集。使用標記整理算法。

              parallel old收集器,用于和parallel scavenge配合使用的年老代收集器,是parallel scavenge的最佳搭檔。

              G1(garbage first)收集器,最前沿的,jdk1.6進入試用期。采用標記-整理算法,并且對新生區分區,分區有不同的優先級,優先收集內存較滿的區域。有著很高的并發和較低的停頓,也算是敏捷的一種收集器。

              5 基本經驗

              minor gc是運行在新生代的gc,major GC是運行在年老代的GC,比minor慢十倍。

              大對象很有可能直接進入年老代,程序中盡量避免短命大對象(數組、列表)。

              一次minor沒被收集,從eden進入survivor,每過一次GC,survivor加一歲,直到N歲進入年老區。

              根據GC的工作原理,我們可以通過一些技巧和方式,讓GC運行更加有效率,更加符合應用程序的要求。一些關于程序設計的幾點建議:

              1)最基本的建議就是盡早釋放無用對象的引用。大多數程序員在使用臨時變量的時候,都是讓引用變量在退出活動域(scope)后,自動設置為 null.我們在使用這種方式時候,必須特別注意一些復雜的對象圖,例如數組,隊列,樹,圖等,這些對象之間有相互引用關系較為復雜。對于這類對象,GC 回收它們一般效率較低。如果程序允許,盡早將不用的引用對象賦為null,這樣可以加速GC的工作。

              2)盡量少用finalize函數。finalize函數是Java提供給程序員一個釋放對象或資源的機會。但是,它會加大GC的工作量,因此盡量少采用finalize方式回收資源。

              3)如果需要使用經常使用的圖片,可以使用soft應用類型。它可以盡可能將圖片保存在內存中,供程序調用,而不引起OutOfMemory.

              4)注意集合數據類型,包括數組,樹,圖,鏈表等數據結構,這些數據結構對GC來說,回收更為復雜。另外,注意一些全局的變量,以及一些靜態變量。這些變量往往容易引起懸掛對象(dangling reference),造成內存浪費。

              5)當程序有一定的等待時間,程序員可以手動執行System.gc(),通知GC運行,但是Java語言規范并不保證GC一定會執行。使用增量式GC可以縮短Java程序的暫停時間。

            【java中JVM虛擬機內存模型詳細說明】相關文章:

            Java的內存模型09-22

            Java虛擬機(JVM)和跨平臺原理05-02

            java內存的詳細介紹06-04

            Linux系統中JVM內存2GB上限的詳解09-03

            如何識別Java中的內存泄漏10-19

            Java虛擬機介紹07-12

            Java數組在內存中是如何存放的08-21

            Java內存回收07-17

            Java虛擬機是什么09-14

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院