Python 的GC模塊主要運(yùn)用了引用計(jì)數(shù)來跟蹤和回收垃圾;通過“標(biāo)記-清除”解決容器對象可能產(chǎn)生的循環(huán)引用問題;通過分代回收以空間換時(shí)間進(jìn)一步提高垃圾回收的效率。
也即采用“引用計(jì)數(shù)“為主(實(shí)時(shí)性,一旦沒有引用,內(nèi)存就直接釋放了),“標(biāo)記-清除”與“分代收集”兩種機(jī)制為輔的策略。 ???????
1. 引用計(jì)數(shù)為每一個(gè)對象維護(hù)一個(gè)引用計(jì)數(shù)器,當(dāng)一個(gè)對象的引用被創(chuàng)建或者復(fù)制時(shí),(對象的引用)計(jì)數(shù)器+1,當(dāng)一個(gè)對象的引用被銷毀時(shí),計(jì)數(shù)器的值-1,當(dāng)計(jì)數(shù)器的值為0時(shí),就意味著對象已經(jīng)再?zèng)]有被使用了,可以將其內(nèi)存釋放掉。
2. 標(biāo)記-清除“標(biāo)記-清除”的出現(xiàn)打破了循環(huán)引用,也就是它只關(guān)注那些可能會(huì)產(chǎn)生循環(huán)引用的對象,Python中的循環(huán)引用總是發(fā)生在容器container對象之間,也就是能夠在內(nèi)部持有其他對象的對象(比如:list、dict、class等)。這也使得該方法帶來的開銷只依賴于容器對象的數(shù)量。
原理:
將集合中對象的引用計(jì)數(shù)復(fù)制一份副本,用于找尋root object集合(該set中的對象是不能被回收的)。當(dāng)成功找到root object集合,首先將現(xiàn)在的內(nèi)存鏈表一分為二,一條鏈表維護(hù)root object集合,成為root鏈表;另外一條維護(hù)剩下的對象,成為unreachable鏈表。
一旦在標(biāo)記的過程中,發(fā)現(xiàn)現(xiàn)在在unreachable鏈表且可能存在被root鏈表中直接或間接引用的對象,就將其從unreachable鏈表中移到root鏈表中;當(dāng)完成標(biāo)記后,unreachable鏈表中剩下的所有對象就是垃圾對象了,接下來的垃圾回收只需限制在unreachable鏈表中即可。
缺點(diǎn):
該機(jī)制所帶來的額外操作和需要回收的內(nèi)存塊成正比。
3. 分代回收活的越長的對象,就越不可能是垃圾,就應(yīng)該減少對它的垃圾收集頻率。
4. 其他4.1 JNI(Java Native Interface)提供了若干的API,實(shí)現(xiàn)Java與其他語言的通信。
總結(jié)本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注好二三四的更多內(nèi)容!