Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 1467] ファイルの概要

このコミットは、Go言語の初期開発段階において、実験的なメモリ管理システムである「playpen copy of malloc」を削除するものです。具体的には、usr/rsc/mem ディレクトリ以下に存在していたカスタムのメモリ割り当て(malloc)実装とその関連ファイル(Makefile、Go言語のインターフェース、C言語のソースコード、ヘッダファイル、テストコードなど)が完全に削除されています。これは、Go言語のランタイムが独自の、より統合されたメモリ管理システムへと移行する過程の一部であり、初期の実験的なコードベースの整理を意味します。

コミット

commit 8b8ff164b3cf622f2394dad0c399c220503f0fb7
Author: Russ Cox <rsc@golang.org>
Date:   Tue Jan 13 16:32:40 2009 -0800

    delete playpen copy of malloc
    
    R=r
    DELTA=905  (0 added, 905 deleted, 0 changed)
    OCL=22663
    CL=22690
--
 usr/rsc/mem/Makefile           |  38 ----
 usr/rsc/mem/allocator.go       |  15 --
 usr/rsc/mem/malloc.c           | 493 -----------------------------------------
 usr/rsc/mem/malloc.h           |  80 -------
 usr/rsc/mem/mem.c              |  39 ----
 usr/rsc/mem/pagemap.c          |  66 ------
 usr/rsc/mem/testrandom.go      |  68 ------
 usr/rsc/mem/testrepeat.go      |  37 ----
 usr/rsc/mem/testsizetoclass.go |  11 -
 usr/rsc/mem/triv.c             |  74 -------
 10 files changed, 921 deletions(-)

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/8b8ff164b3cf622f2394dad0c399c220503f0fb7

元コミット内容

delete playpen copy of malloc

変更の背景

このコミットは、Go言語の初期開発フェーズ、特にメモリ管理システムがまだ確立されていなかった時期に行われました。Go言語はガベージコレクション(GC)を持つ言語であり、効率的なメモリ管理はランタイムの性能に直結する重要な要素です。

コミットメッセージにある「playpen copy of malloc」とは、Go言語のランタイムに統合される前の、実験的または一時的なメモリ割り当て実装を指します。Go言語の初期のコミット履歴を見ると、usr/rsc/mem のような usr ディレクトリ配下は、Russ Cox氏(Go言語の主要開発者の一人)が個人的な実験やプロトタイピングを行っていた領域であることが示唆されます。

この「playpen copy of malloc」は、Googleの高性能メモリ割り当てライブラリであるtcmalloc(Thread-Caching Malloc)の設計思想を取り入れたC言語による実装でした。しかし、Go言語のランタイムは最終的に独自の、よりGoの並行性モデルやガベージコレクションと密接に連携するメモリ管理システム(mheap, mspanなど)を構築することになります。

このコミットは、Go言語のメモリ管理が実験段階から、より永続的で統合されたランタイムの一部としての実装へと移行する節目を示しています。不要になった実験的なコードベースを削除することで、コードの複雑性を減らし、今後の開発を効率化する目的があったと考えられます。

前提知識の解説

メモリ割り当て(malloc)

malloc は "memory allocation" の略で、C言語やC++などのプログラミング言語において、プログラムの実行中に動的にメモリを確保するための標準ライブラリ関数です。malloc は指定されたサイズのメモリブロックをヒープ領域から確保し、そのブロックの先頭アドレスを返します。確保されたメモリは、使用後に free 関数で解放する必要があります。

ガベージコレクション(GC)

ガベージコレクションは、プログラムが動的に確保したメモリのうち、もはやどの部分からも参照されなくなったメモリ領域(「ガベージ」と呼ばれる)を自動的に検出し、解放する仕組みです。これにより、プログラマは手動でのメモリ解放の管理から解放され、メモリリークやダングリングポインタといったエラーのリスクを低減できます。Go言語は、このガベージコレクションを標準で備えています。

tcmalloc

tcmalloc(Thread-Caching Malloc)は、Googleが開発した高性能なメモリ割り当てライブラリです。特にマルチスレッド環境での性能向上に焦点を当てており、各スレッドが独自の小さなメモリキャッシュを持つことで、ロックの競合を減らし、メモリ割り当て・解放の速度を向上させます。Go言語の初期のメモリ管理は、このtcmallocの設計思想から大きな影響を受けていました。

Go言語の初期のメモリ管理

Go言語の初期のメモリ管理は、現在の洗練されたシステムとは異なり、試行錯誤の段階にありました。このコミットで削除された malloc.c は、tcmallocの設計をGoの文脈で試すためのものでした。Goのランタイムは、最終的に独自のメモリ管理メカニズム(mheap、mspan、mcacheなど)を開発し、Goのガベージコレクタと密接に連携するように設計されました。このシステムは、小さなオブジェクトのためのスレッドローカルキャッシュ(tcmallocに似た概念)と、大きなオブジェクトやページ管理のためのグローバルヒープを組み合わせています。

Playpen

ソフトウェア開発における「playpen」とは、実験的なコードやプロトタイプを開発するための隔離された環境や領域を指すことがあります。Go言語の初期のソースコードリポジトリでは、usr/rsc/ のようなパスが、Russ Cox氏の個人的な実験や、Goのコアランタイムに統合される前の試作コードを置く場所として使われていたようです。このコミットは、その「playpen」で開発されていたメモリ割り当てコードが、もはや必要なくなったことを示しています。

技術的詳細

このコミットは、Go言語のランタイムにおけるメモリ管理の進化を示す重要なマイルストーンです。削除されたコードは、Goのランタイムが独自の効率的なメモリ管理システムを構築する前の、一時的な実装でした。

malloc.c のコメントには、tcmallocの設計に言及があり、その目標として「Central free lists」「Thread cache stealing」「Return memory to the OS」「Coalesce adjacent free spans」などが挙げられています。これらは、現代の高性能なメモリ割り当て器が持つべき主要な機能です。

削除されたファイル群は、以下のような役割を担っていました。

  • malloc.cmalloc.h: tcmallocの設計に基づいたC言語によるメモリ割り当て・解放のコアロジック。Span(メモリページの連続したブロック)、Central(中央のフリーリスト)、PageMap(ページ番号からSpanへのマッピング)といった概念が導入されていました。
  • allocator.go: Go言語からC言語の malloc 実装を呼び出すためのインターフェース定義。mallocfreememset などの関数が export されていました。
  • mem.c: stackallocstackfree といった、スタックからのメモリ割り当て・解放に関連する補助関数が含まれていました。
  • pagemap.c: ページ番号をメモリブロックのメタデータ(Span構造体)にマッピングするための多段階ラディックスツリー(radix tree)実装。これは、仮想アドレス空間を効率的に管理するために使用されます。
  • triv.c: trivalloc という「自明な」または「単純な」アロケータの実装。これは、Span 構造体のような小さな内部データ構造や、より大きなメモリブロックをOSから直接取得するために使用されていました。sys·mmap を使用してOSからメモリを要求していました。
  • Makefile: これらのC言語およびGo言語のソースファイルをビルドするためのMakefile。
  • testrandom.go, testrepeat.go, testsizetoclass.go: 削除された malloc 実装のテストコード。ランダムなサイズの割り当て・解放を繰り返したり、特定のサイズクラスへのマッピングをテストしたりしていました。

これらのファイルが削除されたことは、Go言語のランタイムが、これらの実験的なC言語ベースのメモリ管理コードに依存するのをやめ、Go自身のランタイムに完全に統合された、よりGoらしいメモリ管理システムへと移行したことを明確に示しています。これにより、Goのガベージコレクタとメモリ割り当て器がより密接に連携し、Goの並行性モデルに最適化された効率的なメモリ管理が実現されました。

コアとなるコードの変更箇所

このコミットは、既存のコードの削除のみで構成されており、追加や変更されたコードはありません。

削除されたファイルは以下の通りです。

  • usr/rsc/mem/Makefile
  • usr/rsc/mem/allocator.go
  • usr/rsc/mem/malloc.c
  • usr/rsc/mem/malloc.h
  • usr/rsc/mem/mem.c
  • usr/rsc/mem/pagemap.c
  • usr/rsc/mem/testrandom.go
  • usr/rsc/mem/testrepeat.go
  • usr/rsc/mem/testsizetoclass.go
  • usr/rsc/mem/triv.c

コアとなるコードの解説

削除されたファイル群は、Go言語の初期の実験的なメモリ割り当て器の実装でした。

  • malloc.cmalloc.h: これらは、Go言語のランタイムが使用するカスタムのメモリ割り当て器のC言語による実装でした。tcmallocの設計思想を取り入れ、メモリをページ単位で管理し、小さなオブジェクトと大きなオブジェクトで異なる割り当て戦略を持つように設計されていました。Span 構造体はメモリの連続したブロックを表し、Central 構造体は中央のフリーリストを管理し、PageMap は仮想アドレスから Span へのマッピングを提供していました。
  • allocator.go: このGoファイルは、C言語で実装された malloc 関連の関数をGo言語から呼び出すための外部関数宣言(export キーワードを使用)を含んでいました。これにより、GoのコードがこのC言語のメモリ割り当て器を利用できるようになっていました。
  • pagemap.c: ページマップの実装は、仮想メモリ空間を効率的に管理し、特定のアドレスがどのメモリブロック(Span)に属するかを高速に検索するためのデータ構造でした。これは、メモリの解放やガベージコレクションの際に重要となります。
  • triv.c: このファイルは、より基本的なメモリ割り当て機能を提供していました。これは、malloc.c のような複雑なアロケータが内部的に使用する、OSからの生のメモリ取得(sys·mmap を介して)や、小さな内部データ構造の割り当てを担当していました。
  • テストファイル群 (testrandom.go, testrepeat.go, testsizetoclass.go): これらのGoファイルは、削除された malloc 実装の機能と性能を検証するためのテストスイートでした。ランダムなサイズのメモリ割り当てと解放を繰り返したり、特定のサイズクラスへのオブジェクトのマッピングが正しく行われるかを検証したりしていました。

これらのファイルが削除されたことは、Go言語のメモリ管理が、この実験的なC言語ベースの実装から、Go自身のランタイムに深く統合された、よりGoらしいメモリ管理システムへと完全に移行したことを意味します。

関連リンク

参考にした情報源リンク

  • GitHubのコミットページ: https://github.com/golang/go/commit/8b8ff164b3cf622f2394dad0c399c220503f0fb7
  • commit_data/1467.txt の内容
  • Go言語のメモリ管理に関する一般的な知識 (Goのランタイム、ガベージコレクション、mheap/mspan/mcacheの概念)
  • tcmallocに関する一般的な知識
  • C言語の malloc/free に関する一般的な知識
  • Go言語の初期のソースコード構造に関する推測と理解