Open3
Ribbon: GCを実装する

まぁPythonと同様のGCで良いかな。
全ての外部参照を持つ可能性があるオブジェクト(コンテナ)をリンクリストで繋いでおき、
- リストを辿って
gc_ref
をコンテナ自身のリファレンスカウントで初期化 - 再度リストを辿って自身が参照しているコンテナの
gc_ref
を1減算 - 再度リストを辿って
gc_ref
がゼロのコンテナはゴミリストに移動 、同時に、gc_ref
がゼロでないコンテナから参照されているコンテナがゴミリストに入っていたらゴミリストから除いてリストの末尾に追加
このアルゴリズムの良いところは 2 や 3 で再帰する必要が無いことで、超深い再帰リストを作っていたとしても問題なくオブジェクトを回収できる。

なんとなく動いた
リストを修正したらリストのnextを読み直さないといけないのをすっかり忘れていてデバッグにてこずってしまった(初心者かよ)
あと今気付いたけど、
こういう風にリファレンスカウントを手動で操作して無理矢理freeするのはダメで、コンテナじゃないオブジェクトのリファレンスカウントを下げつつ、コンテナは問答無用で解放する (トラバースしない) 専用のFreeを用意する必要がある。このGCで解放されるコンテナは常に非ゼロのリファレンスカウントを持つので、どこかから指されている。

たぶんちゃんと動いた
前の1.1GiB https://zenn.dev/link/comments/e7adbca38ede4c に比べればだいぶまともな処理量だな。
修正前のコードは何故かMSVCとCygwinで挙動が違い、Cygwinだけクラッシュしていた。