問下, C++ 的垃圾回收機制 如何實現的話 要怎麼掃描 bss data 之類的欄位?

問下, c++ 的垃圾回收機制 要怎麼掃描 bss data 之類的欄位

似乎這個沒法程序自己控制

嗯, 想了下, 好像32位程序, 以及64位的程序, 有默認的起始地址, 是不是從那個起始地址開始, 累加然後一個一個位元組往上掃, (掃, 是不是, 每往上一個位元組,然後假設從這個位元組往上的4個位元組/8個位元組, 是一個指針, 然後看看是否指向堆)

嗯, 謝謝啊


如果像大部分C++編譯器這樣在GC上做甩手掌柜,也就是說你自己通過庫或附加的機制實現GC,那隻能根據具體情況來定位data和bss了吧,感覺還不如轉java或用智能指針了


題主這樣提問,感覺是做了實現「保守式GC」(conservative GC)的假設。

關於保守式GC與準確式GC,我以前發過一篇筆記有提到:找出棧上的指針/引用

如果是想為C/C++實現保守式GC,那麼參考成熟的Boehm GC的設計與實現是個不錯的開始。

首先可以閱讀這篇概述文檔:Conservative GC Algorithmic Overview

其中在Mark Phase章節里提到了這個:

Static data region(s). In the simplest case, this is the region between DATASTART and DATAEND, as defined in gcconfig.h. However, in most cases, this will also involve static data regions associated with dynamic libraries. These are identified by the mostly platform-specific code in dyn_load.c.

而它提到的dyn_load.c的實現可以參考這裡:bdwgc/dyn_load.c at master · ivmai/bdwgc · GitHub

可見這是很麻煩而脆弱的一件事…

如果要實現準確式GC的話,從C++代碼里最好是通過某種形式的Handle去訪問能被GC的對象。所謂「handle」就是一個間接指針,通過增加一個GC能發現的間接層來告訴GC哪裡有它需要關心的引用。

可以參考一些用C++實現的虛擬機是怎麼做的。例如:

  • SpiderMonkey:GC Rooting Guide。就題主關心的靜態數據而言,它會建議使用JS::PersistentRooted&類型來引用GC對象。
  • V8:V8 Embedder"s Guide 同樣建議使用它的Persistent系列的handle來引用GC對象。


我覺得你最好別硬掃,而是弄個類似智能指針的類型,用來標記需要被垃圾管理的對象。


這是早期golang使用的垃圾演算法,正確的垃圾回收機制應該100%的確定什麼東西是託管指針,什麼東西不是。如果編譯器做了,那一定會把這些信息帶進去。如果你要自己完成,你可以掃描pdb文件獲取class的layout,然後再做。


推薦閱讀:

XMLHttpRequest對象的生命周期是如何管理的?
為什麼 C++ 11 標準不加入 GC 功能呢?
c++11標準 GC(垃圾回收)是否會使老代碼產生未定義行為?
一個人基於OpenJDK實現GC的concurrent compact部分,以減少GC停頓,困難嗎?
JVM堆內存很富足時,為什麼經常連續發生兩次full GC?

TAG:CC | GC垃圾回收計算機科學 |