golang GC(一 原理)


golang中的gc采用三色標記法。在講三色標記法之前,先了解一下Mark and Sweep算法,因為Mark and Sweep算法是三個標記法的一個改進版。

Mark and Sweep算法: 停止運行程序,遍歷所有被引用的變量,被引用的對象被標記為“被引用”,沒有被標記的進行回收。內存單元並不會立刻回收對象,而是將其標記為“不可達”狀態。直到到達某個閾值或者到達某個時間間隔后,對其進行垃圾回收。算法分為兩部分:標記(Mark)和清理(Sweep)。掛起程序,對所有存活的內存單元進行掃描,標記,確定哪些可以清除。優點是解決了相互引用的缺點,不足是會停止應用程序,當內存單元變量過多時,掃描清除會花很長時間,甚至幾百毫秒。

三色標記法:屬於標記清除法的一個改進版。起初所有內存對象都在白色的,從根出發標記所有的對象,標記為灰色,並放入一個隊列。然后再將灰色隊列中的對象取出,將其引用對象標記為黑色。重復此步驟,待灰色對象隊列為空時,所有白色對象既為垃圾。最后白色區域內存對象被釋放,黑色區域標記為白色,等待下一階段GC再次掃描。

三色標記法觸發有兩個條件:第一個是閥值,就是內存擴大一倍時啟動GC。第二個是每隔兩分鍾GC一次。

 

三色標記法的具體過程

1、GC開始的時候stop the world。對內存中的對象進行掃描。掃描完畢后,start the world。程序繼續運行,GC同時開始標記。

 

2、將線程(goroutine)直接引用的對象標記為灰色,將灰色內存對象標記為黑色。同時將灰色內存對象引用的對象標記為灰色。

 

 

3、反復第2步直到灰色區域為空。此時只有黑色和白色區域了。

 

 

4、stop the world, again! 利用寫屏障機制,將GC掃描時新創建的對象一律標記為灰色,然后變成黑色。

5、將內存對象被標記為白色的進行釋放sweep。

6、剩下的內存全部標記為白色,以便下一次GC使用。

 

如何優化GC 

寫代碼時,如果要考慮GC對性能的影響,那么要避免要用string+操作,改用var buf bytes.Buffer,用buf.WriteString("xxxx")操作。因為沒有string+操作都會生成一個新的string,產生多余的內存碎片。還有就是盡量復用小對象,局部變量需要盡量少聲名,多個小對象可以放到一個結構體中,這樣方便GC掃描。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM