Go の新しいガベージコレクションがヒープを走査していく様子

2026/07/25 16:55

Go の新しいガベージコレクションがヒープを走査していく様子

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

Go の新しい Green Tea ゴー・コレクター(v1.26 以降のデフォルト)と C# を比較した評価から得られる主な示唆は、CPU キャッシュ効率とメモリアン断片化の間にある明確なトレードオフである。Green Tea は連続したスパンへの割り当てを最適化することでキャッシュミスが大幅に減少するが、オブジェクトを解放する際に移動やコンパクト化を行うことはできない。その結果、C# の移動式コレクターが積極的に関与してヒープをコンパクト化し OS に散在ページを返すのと異なり、Go は大量の解放後(例:90% のオブジェクトを解放)も未解放オブジェクトがばら撒かれたままとなる。

裸の金属 x86 システムでのテストにより、この断片化は介入なしに持続することが確認された。しかし、開発者は

unsafe
ポインタを使用して残存するオブジェクトを手動でパッケージ化することでこの制限を回避し、実質的にコンパクト化を模倣してシステムリソースを取り戻すことができる。結論として、Go は真の CPU パフォーマンス向上を提供するものの、複雑な回避策なしにヒープをコンパクト化できないという Go の不具合は依然として大きな制約であり、長期的動作を必要とし効率的なメモリ回収を要求するアプリケーションにおいては、C# が優れたアーキテクチャ上の振る舞いを提供することが組織にとって認識すべき点である。

本文

ソフトウェアインフラ:Go の新 Garbage Collector「Green Tea」とヒープの歩き方

著者:フィル・エイトン
日付:2026 年 7 月 19 日

本記事は購読者限定で先行公開いたします。ご支援により、このような記事の発表が可能となっています。ありがとうございます。

導入:Go のメモリ管理の変化

昨年にリリースされた Go 1.25 では、新しい garbage collector(GC)である「Green Tea」が導入されました。数ヶ月前にリリースされた Go 1.26 からは、これがデフォルトとなりました。

  • 受容的なプログラム: Green Tea を採用することで恩恵を受けられるプログラムが存在します。
  • 課題となるプログラム: Go の旧来型の「残存 garbage collector」が抱える非移動型コレクターによるスパーズ(不連続)なページの回収不能という問題を引き起こすケースについても考察します。

メモリ管理の基本:サイズ階層化とスパン

Go は、メモリの管理において以下の原則を採用しています。

  • サイズ segregated アロケーション: 同じサイズクラスのオブジェクトをまとめます。
  • ページ単位のアロケーション: オブジェクトのサイズを上 nearest なクラスへ丸め上げ、1 つまたは複数の 8KiB ページ(Go の用語では「スパン」)からなる連続領域内に配置します。
    • この手法は Go のアロケータ由来である tcmalloc など、一般的な malloc インプリメンテーションでも見られます。

ヒープの可視化:Go vs C#

異なるサイズのオブジェクトをランダムにアロケートし、その後ヒープアドレスを確認することで、各言語のアロケーション戦略の違いを観察します。

  • 方法: アドレス空間を 32 バイトずつ移動させ、そのタイミングで文字(
    .
    )を出力して視覚化します。

インストール手順

Go と C# を環境にインストールします。

sudo apt update -y
sudo apt-get install -y dotnet-sdk-10.0
curl -fsSL https://go.dev/dl/go1.26.0.linux-amd64.tar.gz | sudo tar -C /usr/local -xz
export PATH=$PATH:/usr/local/go/bin

擬似コードの実装例

Go でヒープの可視化

Go の実装では、オブジェクトが移動しないため、GC を実行する前後でも配置は同一のままです。

実行コマンド:

go run heapwalk.go

出力結果(抜粋):

=== pass 0 (base 0xba4841580c0) ===
0xba4841580c0  M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-M-
             ...
0xba4841add40  ..........................L---L---L---L---L---L---L---L---L-

=== pass 1 (base 0xba4841580c0) ===
// GC を実行しても配置は変化せず、オブジェクトの移動が発生していません。

C# でヒープの可視化

C# では同じサイズのオブジェクトがグループ化されていないことが観察されます。

ビルドと実行:

dotnet run HeapWalk.cs

出力結果(抜粋):

=== pass 0 (base 0x7aea1080a1e0) ===
0x7aea1080a1e0  L---L---L---M-M-SL---L---SM-L---M-L---L---L---M-L---SSL
// ランダムにアロケートされたオブジェクトが混在しています。

比較結果:

  • Go: 同じサイズクラスのオブジェクトは互いに隣接して配置され、ランダムなアロケーションでも秩序立っています。
  • C#: オブジェクトは移動せず、ランダムにアロケートされたままです。(別ワークロードでは C# がメモリ内でもオブジェクトを移動させる場合もありますが、デフォルトでは非移動です。)

マーク&スイープ:キャッシュフレンドリーさの検証

Go の Green Tea GC は、従来の「ポインタを追跡する」というアプローチとは異なる動作をとります。

  • Green Tea の仕組み: スパン全体を走査し、発見したポインタに基づいて後続のスパンをキューイングします。これにより、ランダムなメモリアccess を抑え、キャッシュフレンドリーな動作を実現しています。

検証ワークロード:パッキング vs スカータリング

  • packed: オブジェクトの参照先も隣接したメモリ領域にある(キャッシュフレンドリー)。
  • scattered: 参照先がランダムに配置されている(キャッシュ unfriendly)。

パフォーマンス比較結果(L3 キャッシュミス率など):

  • Green Tea GC は、古い GC に比べて実行時間の改善が見られます。
  • 意外な事実:
    perf
    で測った L3 キャッシュミスの割合は、新しい GC で増加しているように見えますが、これはL1/L2 キャッシュレベルの動作についての直接情報ではないためです。

正規化指標(MPKI)による分析

命令数に対するキャッシュミス率(Misses Per Kilo Instructions: MPKI)で比較すると、以下の結果が出ました。

バージョンワークロードL1-MPKIL3-MPKI
old_gcpacked2.231.61
old_gcscattered31.5712.76
greenteapacked1.98 (↓)1.81 (↑)
greenteascattered14.06 (↓)15.39 (↑)

結論:

  • L1 MPKI(最も重要な指標)は顕著に減少しています。
  • 多くの読み込みが L1/L2 キャッシュに収容され、L3 に到達する必要がなくなりました。
  • Green Tea GC は、少なくともキャッシュ改善の分野で劇的な向上をもたらしています。

最悪ケースの片付け:スパーズなページの問題

Go の非移動型コレクションでは、オブジェクトを解放してもメモリ領域(スパン)自体は未使用のまま残ることがあります。

シナリオ

  1. ランダムにサイズが異なるオブジェクトをアロケート。
  2. その 90% を解放(
    nil
    にする)。
  3. GC を実行し、OS にメモリを返す (
    FreeOSMemory
    )。

結果:Go (Green Tea) の挙動

  • 生き残ったオブジェクトは移動しないため、解放された領域と混在したスパンが解放されません。
  • メモリ使用量は期待通り減少せず、不連続なページが残ります。

出力(抜粋):

=== pass 1 (5000 live, ...) ===
  spans pinned   463      (46 if the survivors were packed) // 理想値は 46 個だが、463 のスパンが使われています。
  HeapReleased    5512.0 KiB

対策:手動でのパッキング(Go)

オブジェクトをコピーして同じ位置に再配置することでフラグメンテーションを解消できますが、これは Go ランタイムの機能ではありません。

出力(手動パッキング後):

=== pass 2 (5000 live, base shifted) ===
// オブジェクトが連続した領域にまとめられています。
  spans pinned         48      (47 if the survivors were packed) // スパン数が大幅に減少。
  HeapReleased          9040.0 KiB   // OS に返されるメモリが増加。

C# の片付けとの比較

C# では、GC がデフォルトで**フルコンパクション(Full Compaction)**を行うため、解放されたオブジェクトの処理に大きな違いが出ます。

C# の挙動

  • GC.Collect(GC.MaxGeneration, GCCollectionMode.Aggressive)
    を実行すると、解放可能なメモリは即座に整理され、OS に返されます。
  • 生き残ったオブジェクトが移動し、連続した領域になります。

出力(抜粋):

=== pass 1 (5000 live, ...) ===
  8KiB chunks          47      (47 if the survivors were packed) // パッキング済みとして最適化されています。
// C# の GC は自動的にスパーズなページの問題を解決しています。

結論

  • Go: Green Tea GC はキャッシュパフォーマンスを劇的に向上させました。しかし、非移動型であるため、解放後のメモリ整理(Defragmentation)には開発者の介入や手動パッキングが必要です。
  • C#: GC が自動的にオブジェクトを移動・整理するため、メモリの不連続な領域が残りやすく、OS に返せなくなります。ただし、フルコレクション実行後は常に整理された状態になります。

Go の Green Tea GC は、キャッシュ性能を最適化する一方で、メモリ配置の整理については依然として開発者の理解と管理が必要であることを示しています。

同じ日のほかのニュース

一覧に戻る →

2026/07/28 7:03

オープンウェイトモデルに関する当社の立場

## Japanese Translation: Anthropic の CEO ダリオ・アモデイは、オープンウェイトの AI モデルに対する全面的な禁止に反対し、同社がそのような制限を支持したことはないと主張している。彼は、危険な能力を持たないオープンウェイトモデルを不可欠な公共財として位置づけ、主な国家安全保障上の懸念として、共産主義中国(CCP)などの権威主義体制が、恒久的な軍事優位や抑圧のために優れた AI を構築しようとするリスクを挙げており、このリスクは副大統領ヴァンスの最近の警告や米国当局による世界的競争力に関する情報評価によって強調されている。彼の二次的な懸念には、サイバー攻撃、生物学的脅威、またはアライメント(調整)失敗への悪用が含まれる。アモデイは、オープンウェイトモデルはガードレールの実行が難しく、リリースされた重み(weights)を回収できないため、閉鎖型モデルよりも高いリスクをもたらすと指摘している。これらの脅威を緩和しつつ有益なイノベーションを維持するため、彼は以下の目標志向戦略を提唱している:中国への高度な半導体および装備の輸出制限、モデルの密輸入や産業規模での蒸留(distillation)操作への取り締まり、そして公開前に十分に能力のあるすべてのモデルに対して安全性テストの実施を義務付ける。彼は、全面的な禁止は効果的でもなく、Anthropic が求める解決策でもないとし、代わりに回収不能なシステムにおけるリスク管理を進めつつ、安全性にコミットしている者にとってのアクセスを維持することを主張している。

2026/07/28 4:58

HN ランチ:Rise(YC S26)——廃棄物ガスを貴重な化学物質に変える

## Japanese Translation: Rise Reforming は、シカゴ郊外の下水処理施設でパイロットプラントの建設を正式に開始し、2026 年 7 月の稼働を目指しています。2025 年 12 月には 65 万ドルの前種投資を受け、初雇用の Nina Kritikos を擁し、同社は 2026 年 4 月に 1,800 時間以上の連続運転を通じて安定した概念実証結果を達成しました。また、プロジェクトはバイオガス生産者との拘束力のある供給契約および複数の覚書(MOU)を確保しています。 同社の固有技術では、下水処理廠などの発生源から排出される国内の滞留バイオガス(廃棄ガス)をメタノール、ジメチルエーテル(DME)、ジメチルカーボネート(DMC)といったグリーン化学物質に変換します。このアプローチは、化石燃料の採掘・精製・輸送に伴う環境コストを回避する低価格な代替策を提供することで、従来の石油化学製品と直接的に競合しています。主要な革新点は、許可手続きの長期遅延なく特定の施設の要件に合わせて迅速に導入および容易にスケールアップ可能なモジュール式でコンテナサイズの設計にあります。 Rise Reforming は 2026 年 7 月、成長とスケールアップのさらなる加速のために Y Combinator の S26 バッチに参加しました。廃棄物を価値ある化学物質に変えることで、即座の財政的リターンを提供しつつクリーンなエネルギー未来を支援することを目的としています。過去のマイルストーンには、2025 年 5 月に European Aerosols Federation 2025 Start-Up Award を受賞し、George Rose が 776 Foundation から Climate Fellow に選出されたことが含まれます。

2026/07/28 3:43

完全に自律した高機動性のPython配布パッケージ

## Japanese Translation: このプロジェクトは、Linux、macOS、Windows すべてで複雑な展開課題を解決する、非常にポータブルな単一ファイルの Python 配布物を提供します。依存関係を静的にリンクするかアーカイブ内に分布させることで、不安定な外部共有ライブラリを排除し、いずれかのターゲットシステムアーキテクチャにおいて即時の実行準備が整うことを保証します。PyOxy という姉妹プロジェクトは、これらの配布物に Rust コードを追加することで Python インタプリターの機能を強化し、公式の PyOxy リリースバイナリは、CPU 指示命令と依存関係を厳格に制限する完全機能を持つインタプリターを単一ファイルの実行可能プログラムとしてパッケージ化しています。 配布物は「フルアーカイブ」と「インストール専用アーカイブ」の 2 つのタイプで利用可能です。「フルアーカイブ」にはすべて必要なものが含まれ、「インストール専用アーカイブ」は下流のリパッケージ向けに設計されています。この柔軟性により、開発者は SQLite や OpenSSL のようなオプション機能を除いて独自の配布物を作成することができ、これは Python をより大きなバイナリ内に埋め込むために不可欠です。本解決策はプラットフォーム固有の癖(例:Windows での特殊なキー処理や pip.exe や tix といったツールの欠落)に対応するとともに、共有ライブラリの設定を除去することで実行時複雑性を大幅に削減します。エンジニアは、展開および管理が容易でありながら重要な標準ライブラリ拡張モジュールへのアクセスを維持できる、簡素化された埋め込み Python アプリケーションを構築できるようになります。

Go の新しいガベージコレクションがヒープを走査していく様子 | そっか~ニュース