#第一組循環引用# a = [1,2] b = [3,4] a.append(b) b.append(a) del a ## #第二組循環引用# c = [4,5] d = [5,6] c.append(d) d.append(c) del c del d #至此,原a和原c和原d所引用的對象的引用計數都爲1,b所引用的對象的引用計數爲2,
e [7,8]
del e
如今說明一下標記清除:代碼運行到上面這塊了,此時,咱們的本意是想清除掉c和d和e所引用的對象,而保留a和b所引用的對象。可是c和d所引用對象的引用計數都是非零,原來的簡單的方法只能清除掉e,c和d所引用對象目前還在內存中。app
假設,此時咱們預先設定的週期時間到了,此時該標記清除大顯身手了。他的任務就是,在a,b,c,d四個可變對象中,找出真正須要清理的c和d,而保留a和b。spa
首先,他先劃分出兩撥,一撥叫root object(存活組),一撥叫unreachable(死亡組)。而後,他把各個對象的引用計數複製出來,對這個副本進行引用環的摘除。摘除完畢,此時a的引用計數的副本是0,b的引用計數的副本是1,c和d的引用計數的副本都是0。那麼先把副本爲非0的放到存活組,副本爲0的打入死亡組。若是就這樣結束的話,就錯殺了a了,由於b還要用,咱們把a所引用的對象在內存中清除了b還能用嗎?顯然還得在審一遍,別把無辜的人也給殺了,因而他就在存活組裏,對每一個對象都分析一遍,因爲目前存活組只有b,那麼他只對b分析,由於b要存活,因此b裏的元素也要存活,因而在b中就發現了原a所指向的對象,因而就把他從死亡組中解救出來。至此,進過了一審和二審,最終把全部的任然在死亡組中的對象統統殺掉,而root object繼續存活。b所指向的對象引用計數任然是2,原a所指向的對象的引用計數仍然是1code