Java內存模型及GC原理

感謝有奉獻精神的人

轉自:http://blog.sina.com.cn/s/blog_4e90b3ba0100m5cb.html


java內存模型

Java內存模型及GC原理

Java內存模型及GC原理


sun官方網站sun java 虛擬機模型

Java內存模型及GC原理


JVM內存模型中分兩大塊,一塊是 NEW Generation, 另一塊是Old Generation. 在New Generation中,有一個叫Eden的空間,主要是用來存放新生的對象,還有兩個Survivor Spaces(from,to), 它們用來存放每次垃圾回收後存活下來的對象。在Old Generation中,主要存放應用程序中生命週期長的內存對象,還有個Permanent Generation,主要用來放JVM自己的反射對象,比如類對象和方法對象等。

在New Generation塊中,垃圾回收一般用Copying的算法,速度快。每次GC的時候,存活下來的對象首先由Eden拷貝到某個Survivor Space, 當Survivor Space空間滿了後, 剩下的live對象就被直接拷貝到Old Generation中去。因此,每次GC後,Eden內存塊會被清空。在Old Generation塊中,垃圾回收一般用mark-compact的算法,速度慢些,但減少內存要求.
垃圾回收分多級,0級爲全部(Full)的垃圾回收,會回收OLD段中的垃圾;1級或以上爲部分垃圾回收,只會回收NEW中的垃圾,內存溢出通常發生於OLD段或Perm段垃圾回收後,仍然無內存空間容納新的Java對象的情況。

 

1,out of memory 只發生在jvm對old和perm generation 回收後還不能獲足夠內存的情況.

當一個URL被訪問時,內存申請過程如下:
A. JVM會試圖爲相關Java對象在Eden中初始化一塊內存區域
B. 當Eden空間足夠時,內存申請結束。否則到下一步
C. JVM試圖釋放在Eden中所有不活躍的對象(這屬於1或更高級的垃圾回收), 釋放後若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區
D. Survivor區被用來作爲Eden及OLD的中間交換區域,當OLD區空間足夠時,Survivor區的對象會被移到Old區,否則會被保留在Survivor區
E. 當OLD區空間不夠時,JVM會在OLD區進行完全的垃圾收集(0級)
F. 完全垃圾收集後,若Survivor及OLD區仍然無法存放從Eden複製過來的部分對象,導致JVM無法在Eden區爲新對象創建內存區域,則出現”out of memory錯誤”


造成full gc的原因:

new了很多對象,沒有即時在主動釋放掉->Eden內存不夠用->不斷把對象往old遷移->old滿了->full gc

full gc 如何預防,:

1,使用了緩存

      訪問有兩種,第一種是緩存命中率不高的訪問,第二種種是緩存命中率很高的訪問.對於第一種情況,就沒必要緩存了,緩存反而效果不好,浪費內存,沒有提升程序效率還浪費空間,特別是如果這種訪問量級別很大的時候還會導致full gc.第二種情況,不得不緩存很多對象,不緩存的話就要調用數據庫或者其它是要發生io的,所以這時候要不就是想辦法減少緩存對象的大小,例如不緩存沒必要緩存的數據,或者合併一些數據減少內存的使用.如果還是不行那就加機器,加內存.

       總結:在不影響功能的情況下,緩存對象越小越要,命中率越高越好.低命中率的緩存對象還不如不緩存.

2,沒使用緩存的情況,貌似不會出現full gc的情況,除非內存太小,或者設置不對,程序有漏洞.


發佈了103 篇原創文章 · 獲贊 60 · 訪問量 70萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章