天天看點

JVM GC一個對象的朝生夕死 一,假如活在一個沒有分代的連續記憶體中 二,two part三,s0,s1 Eden部分 四,s部分作用 五,s0與s1

   假設程式占用的記憶體是從0000~FFFF這個位址,現在程式執行到給一個對象配置設定記憶體的那部分代碼,給這個對象配置設定了2345~2346這段記憶體,程式繼續執行,到了某一個時刻,程式配置設定的記憶體位址用完了,這時候,程式要回收這段位址裡面,已經無用的對象,那麼,它首先要從頭到尾掃描一遍,然後把其中沒用的位址空間找到,之後将對象占用位址的起始位置和終止位置進行一個向上或者向下的移動,将不連續的位址變成連續的位址空間,打掃房間結束,程式繼續配置設定記憶體執行程式;在一整塊連續的記憶體中,進行所有對象的配置設定,方式是比較簡單的,但是就是每次都要從頭到尾的掃描一遍,如果程式占用的記憶體非常大,或者程式需要對外部響應非常及時,這時候,就會出現很大的問題了。

     将可用記憶體分為:常回收記憶體部分+不常回收部分。按照對象是否經常被回收進行配置設定記憶體。對象建立之後,先放入常常進行垃圾回收的記憶體空間中,如果好久不釋放,再放入不常回收的部分。需要制定一個标準或者規則,來定義多久對象從常回收部分移動到不常被回收的部分。

    這部分主要是為了說明為什麼要分代回收。

   這三部分都屬于新生代,對象被建立之後,首先放入Eden中,經過一次Minor GC,被放入From Survivor,再次Minor GC,想象你此時身處From Survivor中,你身邊有着經曆過16此Minor GC還活着的老對象,它們被移動到了老年代中,還有像你似的,隻經曆過一兩次的,你們一起被複制到了To Survivor中,最後,From Survivor空了,Eden也空了,之後,To Survivor連續整齊的排列着熬下來還屬于青年的新生代對象,From Survivor與To進行交換,此時,你又回到了From survivor中,靜靜地等着下一個時鐘周期的到來。。

   如果沒有s部分,每次新建立的對象,先被放到Eden,滿了之後,放到老年代,老年代滿了,full gc,你會發現,full gc其實是很頻繁的,為了不經常對老年代進行回收,就要把年輕代裡面對象的回收,做的過程久一點,放入到老年代的條件嚴格一點兒,是以加入一個中間緩沖帶S。

     試想如果僅有s,在某個對新生代回收的時刻,這時候,在Eden與S部分,都有不連續的記憶體空間,合并之後,空間還是不連續的,有時候可能會出現這種情況,給一個對象配置設定空間,總的剩餘容量是足夠的,但是沒有連續的空間可以達到對象的大小,這就尴尬了。是以,為了減少這種碎碎念的出現,s拆分為s0,s1,兩部分采用複制算法進行對象交換,保證了在某個時刻,一個s是空的,另一個空間是連續的。