今天發現了一個JVM內存模型不錯的網址,在此分享,以供更多人學習: http://www.javashuo.com/article/p-tloibpbz-ew.htmlhtml
程序猿的平常——JVM內存模型與垃圾回收 Java開發有個很基礎的問題,雖然咱們平時接觸的很少,可是瞭解它卻成爲Java開發的必備基礎——這就是JVM。在C++中咱們須要手動申請內存而後釋放內存,不然就會出現對象已經再也不使用內存卻仍被佔用的狀況。在Java中JVM內置了垃圾回收的機制,幫助開發者承擔對象的建立和釋放的工做,極大的減輕了開發的負擔。那是否是咱們就不須要了解JVM了,顯然在作一些優化或者深刻研究應用性能的時候,JVM仍是起了很關鍵的做用的。所以本篇就總結性的描述下JVM的內存模型與垃圾回收相關的知識。java
本文的主要內容以下:算法
內存模型 垃圾回收 參考文章 內存模型多線程
各部分的功能 這幾個存儲區最主要的就是棧區和堆區,那麼什麼是棧什麼是堆呢?說的簡單點,棧裏面存放的是基本的數據類型和引用,而堆裏面則是存放各類對象實例的。併發
堆與棧分開設計是爲何呢?性能
棧存儲了處理邏輯、堆存儲了具體的數據,這樣隔離設計更爲清晰 堆與棧分離,使得堆能夠被多個棧共享。 棧保存了上下文的信息,所以只能向上增加;而堆是動態分配 棧的大小能夠經過-XSs設置,若是不足的話,會引發java.lang.StackOverflowError的異常學習
棧區 線程私有,生命週期與線程相同。每一個方法執行的時候都會建立一個棧幀(stack frame)用於存放 局部變量表、操做棧、動態連接、方法出口。優化
堆 存放對象實例,全部的對象的內存都在這裏分配。垃圾回收主要就是做用於這裏的。.net
堆得內存由-Xms指定,默認是物理內存的1/64;最大的內存由-Xmx指定,默認是物理內存的1/4。 默認空餘的堆內存小於40%時,就會增大,直到-Xmx設置的內存。具體的比例能夠由-XX:MinHeapFreeRatio指定 空餘的內存大於70%時,就會減小內存,直到-Xms設置的大小。具體由-XX:MaxHeapFreeRatio指定。 所以通常都建議把這兩個參數設置成同樣大,能夠避免JVM在不斷調整大小。線程
程序計數器 這裏記錄了線程執行的字節碼的行號,在分支、循環、跳轉、異常、線程恢復等都依賴這個計數器。
方法區 類型信息、字段信息、方法信息、其餘信息
總結
名稱 特徵 做用 配置 異常 棧區 線程私有,使用一段連續的內存空間 存放局部變量表、操做棧、動態連接、方法出口 -XSs StackOverflowError OutOfMemoryError 堆 線程共享,生命週期與虛擬機相同 保存對象實例 -Xms -Xmx -Xmn OutOfMemoryError 程序計數器 線程私有、佔用內存小 字節碼行號 無 無 方法區 線程共享 存儲類加載信息、常量、靜態變量等 -XX:PermSize -XX:MaxPermSize OutOfMemoryError 垃圾回收 如何定義垃圾 有兩種方式,一種是引用計數(可是沒法解決循環引用的問題);另外一種就是可達性分析。
判斷對象能夠回收的狀況:
顯示的把某個引用置位NULL或者指向別的對象 局部引用指向的對象 弱引用關聯的對象 垃圾回收的方法 Mark-Sweep標記-清除算法
這種方法優勢就是減小停頓時間,可是缺點是會形成內存碎片。
Copying複製算法
這種方法不涉及到對象的刪除,只是把可用的對象從一個地方拷貝到另外一個地方,所以適合大量對象回收的場景,好比新生代的回收。
Mark-Compact標記-整理算法
這種方法能夠解決內存碎片問題,可是會增長停頓時間。
Generational Collection 分代收集 最後的這種方法是前面幾種的合體,即目前JVM主要採起的一種方法,思想就是把JVM分紅不一樣的區域。每種區域使用不一樣的垃圾回收方法。
上面能夠看到堆分紅三個區域:
新生代(Young Generation):用於存放新建立的對象,採用複製回收方法,若是在s0和s1之間複製必定次數後,轉移到年老代中。這裏的垃圾回收叫作minor GC; 年老代(Old Generation):這些對象垃圾回收的頻率較低,採用的標記整理方法,這裏的垃圾回收叫作 major GC。 永久代(Permanent Generation):存放Java自己的一些數據,當類再也不使用時,也會被回收。 這裏能夠詳細的說一下新生代複製回收的算法流程:
在新生代中,分爲三個區:Eden, from survivor, to survior。
當觸發minor GC時,會先把Eden中存活的對象複製到to Survivor中; 而後再看from survivor,若是次數達到年老代的標準,就複製到年老代中;若是沒有達到則複製到to survivor中,若是to survivor滿了,則複製到年老代中。 而後調換from survivor 和 to survivor的名字,保證每次to survivor都是空的等待對象複製到那裏的。 垃圾回收器
串行收集器 Serial 這種收集器就是以單線程的方式收集,垃圾回收的時候其餘線程也不能工做。
並行收集器 Parallel 以多線程的方式進行收集
併發標記清除收集器 Concurrent Mark Sweep Collector, CMS 大體的流程爲:初始標記--併發標記--從新標記--併發清除
G1收集器 Garbage First Collector 大體的流程爲:初始標記--併發標記--最終標記--篩選回收
參考 JVM內存模型:http://developer.51cto.com/art/200911/165015.htm 垃圾回收:http://www.importnew.com/19085.html JVM垃圾回收器:http://www.cnblogs.com/chengxuyuanzhilu/p/7088316.html 內存模型: http://blog.csdn.net/u012152619/article/details/46968883