1. 程式人生 > >JVM內存模型理解

JVM內存模型理解

產生 得到 碎片 統一 itl src tof 緩存 部分

Java虛擬機(Java VirtualMachine 簡稱JVM)是運行所有Java程序的抽象計算機,是Java語言的運行環境,它是Java 最具吸引力的特性之一。

JVM內存模型

技術分享

1.方法區和堆是所有線程共享的數據區

1):存放對象的實例 2)方法區:存放已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼 3)運行時常量池:是方法區的一部分,存放Class的版本、字段、方法、接口等描述信息,字符串池就是這個!!! 2.程序計數器、虛擬機棧、本地方法棧是線程隔離的數據區 4)程序計數器:當前線程所執行字節碼的行號指示器 5)虛擬機棧:描述Java方法執行的內存模型,每個方法被執行時都會創建一個棧幀,用於存儲變量表、操作棧、動態連接、方法出口等信息 6)本地方法棧
:和虛擬機站作用相似,本地方法棧是為虛擬機使用到native方法服務。虛擬機棧則為虛擬機執行Java方法服務。 ps. native方法常用於兩種情況 : (1) 在方法中調用一些不是由java語言寫的代碼;(2)在方法中用java語言直接操縱計算機硬件 參考 : JVM初探 - JVM內存模型 (http://blog.csdn.net/zjf280441589/article/details/53437703)

何時回收-對象生死判定

1、引用計數法:很難解決對象之間相互循環引用問題 2、根搜索算法(GC Roots Tracing):以GCRoots作為起點,如果從GCRoots到一個對象不可達,則該對象是可回收對象 [舉例]如下圖: Object5、6、7
雖然互有關聯, 但它們到GC Roots是不可達的, 因此也會被判定為可回收的對象:
技術分享 參考 : JVM內存分配、GC原理與垃圾回收器 (http://www.importnew.com/23035.html)

GC原理- 垃圾收集算法

1、新生代 - 標記復制算法 : 直接把未清理的對象移動到新的內存,就不會有碎片了(代價小,只要修改堆頭指針就可以,但是浪費的內存很多)   該算法的核心是將可用內存按容量劃分為大小相等的兩塊, 每次只用其中一塊, 當這一塊的內存用完, 就將還存活的對象復制到另外一塊上面, 然後把已使用過的內存空間一次清理掉.

  現代商用VM的新生代均采用復制算法, 但由於新生代中的98%的對象都是生存周期極短的, 因此並不需完全按照1∶1的比例劃分新生代空間, 而是將新生代劃分為一塊較大的Eden區和兩塊較小的Survivor區

(HotSpot默認Eden和Survivor的大小比例為8∶1), 每次只用Eden和其中一塊Survivor. 當發生MinorGC時, 將Eden和Survivor中還存活著的對象一次性地拷貝到另外一塊Survivor上, 最後清理掉Eden和剛才用過的Survivor的空間. 當Survivor空間不夠用(不足以保存尚存活的對象)時, 需要依賴老年代進行空間分配擔保機制, 這部分內存直接進入老年代.

技術分享

2、老年代 - 標記清理算法:直接清理會產生很多碎片

該算法分為“標記”和“清除”兩個階段: 首先標記出所有需要回收的對象(可達性分析), 在標記完成後統一清理掉所有被標記的對象.

技術分享

該算法會有以下兩個問題:
1. 效率問題: 標記和清除過程的效率都不高;
2. 空間問題: 標記清除後會產生大量不連續的內存碎片, 空間碎片太多可能會導致在運行過程中需要分配較大對象時無法找到足夠的連續內存而不得不提前觸發另一次垃圾收集.

3.老年代 - 標記整理算法:讓存活的對象都往前面移動,排除碎片(代價大,移動過多,不浪費內存)

技術分享

4.分代收集算法:當發現剩余對象少時,直接使用標記復制算法,否則使用標記整理算法 參考 : JVM內存分配、GC原理與垃圾回收器 (http://www.importnew.com/23035.html)

java對象的強引用,軟引用,弱引用和虛引用

1、強引用(Strong Reference):不能回收   以前我們使用的大部分引用實際上都是強引用,這是使用最普遍的引用。如果一個對象具有強引用,那就類似於必不可少的生活用品,垃圾回收器絕不會回收它。當內存空間不足,Java虛擬機寧願拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足問題。 2、軟引用(Soft Reference):當內存不夠用的時候可以回收   如果一個對象只具有軟引用,那就類似於可有可物的生活用品。如果內存空間足夠,垃圾回收器就不會回收它,如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高速緩存。
  軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被垃圾回收,JAVA虛擬機就會把這個軟引用加入到與之關聯的引用隊列中。 3、弱引用(Weak Reference):下一次垃圾回收就會被回收

  如果一個對象只具有弱引用,那就類似於可有可物的生活用品。弱引用與軟引用的區別在於:只具有弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。不過,由於垃圾回收器是一個優先級很低的線程, 因此不一定會很快發現那些只具有弱引用的對象。
弱引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果弱引用所引用的對象被垃圾回收,Java虛擬機就會把這個弱引用加入到與之關聯的引用隊列中。

4、虛引用(Phantom Reference):無法通過虛引用得到一個對象,唯一的目的就是為了被回收時收到通知

  "虛引用"顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定對象的生命周期。如果一個對象僅持有虛引用,那麽它就和沒有任何引用一樣,在任何時候都可能被垃圾回收。

  虛引用主要用來跟蹤對象被垃圾回收的活動。虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用隊列(ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之關聯的引用隊列中。程序可以通過判斷引用隊列中是 否已經加入了虛引用,來了解被引用的對象是否將要被垃圾回收。程序如果發現某個虛引用已經被加入到引用隊列,那麽就可以在所引用的對象的內存被回收之前采取必要的行動。

JVM內存模型理解