HN 日本語サマリー

← 一覧へ戻る
プログラミング

malloc()アルゴリズムの比較

Comparison of Malloc() Algorithms (egbert.net)

120 pointsby egberts132 コメント

要約

この記事は、マルチスレッド環境におけるmalloc()のパフォーマンスボトルネックと、メモリ割り当てアルゴリズムの進化について論じています。スタックベースの割り当てから動的スキーム、ガベージコレクション、そして異なるメモリタイプやアーキテクチャを管理するための「アリーナ」の導入に至るまでの進化を詳述しています。さらに、スレッドセーフティ、パフォーマンス、NUMA対応などの観点から、jemalloc、tcmalloc、mimallocといった様々なアロケータの詳細な比較表を提供しています。

全文翻訳

2026年1月20日 malloc()におけるアリーナアーキテクチャの比較

メモリ割り当て

問題点

必要でない限り、メモリ割り当てを制限する

マルチスレッドプログラムは、ヒープがボトルネックとなるため、多くの場合スケールしません。

複数のスレッドが同時にアロケータからメモリを割り当てたり解放したりすると、アロケータはそれらをシリアル化します。アロケータを集中的に使用するプログラムは、プロセッサ数が増えるにつれて実際に遅くなります。

Malloc (libc) は使用するのに最も悪いメモリ割り当てAPIです。

プログラムは、可能であれば、メモリの割り当て/解放を頻繁に行わないようにすべきです。特に、パケットを受信するたびに割り当て/解放するのは避けるべきです。

Linuxカーネルには、skbuff(送受信パケットを格納するために使用されるカーネルメモリ)をリサイクルするためのカーネル/ドライバパッチが利用可能です。

ドライバ内でPF_RINGを使用すると、メモリ割り当てなしでNICからサーキュラーバッファにパケットをコピーできるため、キャプチャパフォーマンスが約10%向上し、輻輳問題が軽減されます。

設計の進化

malloc() の基本的な設計は、OSから動的にメモリプールを事前割り当てし、アプリケーションがそこからより小さな断片を取得できるようにすることです。malloc() は、さまざまな割り当てアルゴリズムを選択できる標準APIであり、割り当て時に高価なOSシステムコール(通常はプログラム初期化時に実行される)を軽減するためにシステムメモリを割り当てます。最初のメモリ割り当てスキームは、スタックベースのメモリ割り当てから始まりました。

次に、リンクリストとバケットヒープメカニズムを使用して、サイズクラスアプローチでプライベートヒープを分割する、動的ベースのメモリ割り当てスキームが登場しました。

やがて、ガベージコレクションアルゴリズムがメモリ割り当てスキームの初期バックエンドとして導入されました。フロントエンドは、通常の malloc() APIなどをカバーします。

2006年には、3番目のプール(オペレーティングシステムメモリプールとライブラリベースのメモリプールに次ぐ)として「アリーナ」が導入されました。アリーナはjemallocの用語であり、異なる速度のメモリバンクやNUMAアーキテクチャ、あるいは複数のCPUコアやCPUインフィニティにそれぞれ紐づけられたメモリなど、異なるメモリタイプを扱うことを意図しています。

フロントエンドの進化

フロントエンドは、アプリケーションに提供されるメモリを管理します。

メモリ割り当てシステムのフロントエンド内では、進化は以下の順序で進みました。

  1. リンクリストフリースペース
  2. ヒープバケットサイズクラス(オブジェクトヘッダを排除)
  3. (プロセス)オーナーエンコーディング
  4. シングルコアローカル割り当てバッファ(CLABs)
  5. エポックエンコーディング
  6. 直接 mmap() による大サイズクラスメモリブロック
  7. ハザードポインタ(ロックフリーオブジェクトの安全なメモリ回収)(M.M. Michael, 2004)
  8. アリーナメモリプール(CPU/コアおよびスレッドごとに分離)
  9. スレッド固有ローカル割り当てバッファ(TLABs)
  10. 定数時間モジュロ同期(OSプールへの早期返却、またはFreeBSDの madvise 呼び出し)

バックエンドの進化

メモリ割り当てシステムのバックエンドは、空き、散在、断片化、または使用されなくなったメモリブロックをOSに返却(これによりRSSを削減)することを管理します。

  • プールセマンティクス:リモートf-リストエンコーディング(Treiberスタックを使用)(R.K. Treiber, 1986)
  • バディアルゴリズム
  • バイナリバディアルゴリズム
  • BIPOPテーブル(スパンベースアロケータ)(S. Schneider, 2006)別名ローカルフリーリストとリモートフリーリスト
  • セグメントキュー(準線形化可能性、Y. Afek, 2010)
  • マルチコア分散キュー(A. Haas, 2013)
  • k-FIFOキュー(T.A. Henzinger, 2013)

競合

より優れたものが存在し、より多くのスレッド/プロセスがメモリ割り当てシステムコールを実行しても悪化しないものがあります。これらはパフォーマンスの良い順にリストアップされています [ソース付き]

malloc設計の比較

アロケータ起源 / メンテナスレッドセーフスレッドごとのキャッシュマルチアリーナ / ヒープロックフリー高速パスNUMA対応断片化制御メモ
dlmallocDoug LeaNoNoNoNoLowSingle global heap; basis for many later allocators後続のアロケータの多くがベース
ptmalloc2 / ptmalloc3glibcYesLimitedYesNoMediumglibc default; arena locks cause contentionglibcデフォルト; アリーナロックが競合を引き起こす
glibc malloc (current)GNUYesLimitedYesNoMediumWrapper around ptmalloc with tunablesptmallocのラッパー、チューニング可能
jemallocFreeBSD / MetaYesYesYesPartialHighThread-arena affinity reduces CAS contentionスレッドとアリーナの親和性がCAS競合を軽減
tcmallocGoogleYesYesYesPartialMedium-HighPer-CPU caches; central freelists still existCPUごとのキャッシュ; 中央フリーリストが存在
mimallocMicrosoftYesYesYesYesHighDesigned to minimize atomic ops and false sharingアトミック操作と偽共有を最小化するように設計
HoardEmery BergerYesYesYesPartialMediumFocus on scalability and false-sharing avoidanceスケーラビリティと偽共有回避に注力
nedmallocNEDMALLOCYesYesYesNoMediumdlmalloc-derived with thread cachingスレッドキャッシングを備えたdlmalloc派生
phkmallocFreeBSDYesYesYesNoMediumEarly FreeBSD allocator family初期のFreeBSDアロケータファミリー
libumemSolarisYesYesYesYesMedium-HighSolaris allocator with debugging and locality supportデバッグとローカリティサポートを備えたSolarisアロケータ
mtmallocSolarisYesYesYesYesMediumSolaris multithreaded allocatorSolarisマルチスレッドアロケータ
snmallocMicrosoft ResearchYesYesYesYesHighNUMA-awaresecurity- and scalability-focused
lockless malloc (research)Academic / ExperimentalVariesYesVariesYesLowOften CAS-heavy; not production readyCAS多用; 本番環境には適さない
ltallocAcademic

CAS、アトミック競合特性

CAS / アトミック競合特性

アロケータ割り当て/解放あたりの推定アトミック数共有キャッシュラインリスクCAS競合感度メモ
dlmallocHighHighVery Highグローバル構造体とロックが支配的
ptmalloc2 / ptmalloc3Medium-HighHighHighアリーナロックがキャッシュラインのバウンスを引き起こす
glibc malloc (current)Medium-HighHighHighptmallocのラッパー
jemallocLowLowLowアリーナローカルメタデータ; 共有CASは最小限
tcmallocLow-MediumMediumMediumCPUごとのキャッシュ; 中央フリーリストCAS
mimallocVery LowVery LowVery Lowアトミック操作を最小化するように設計
HoardMediumMediumMedium偽共有を軽減するが同期は必要
nedmallocMediumMediumMediumスレッドキャッシュはCASを削減するが排除はしない
phkmallocMediumMediumMedium古いFreeBSD設計
libumemLowLowLowSolarisでのロックフリー高速パス
mtmallocLowLowLowスレッドごとの構造体がアトミック共有を削減
snmallocVery LowVery LowVery Lowメッセージパッシングモデルが共有CASを回避
lockless malloc (research)HighHighHighロックなしでもCAS多用

NUMA、メモリローカリティ特性

NUMA / メモリローカリティ特性

アロケータ明示的なNUMAサポートファーストタッチフレンドリークロスNUMAトラフィックリスクローカリティ維持メモ
dlmallocNoYesVery HighPoor単一ヒープがノードをまたぐ
ptmalloc2 / ptmalloc3NoPartialHighFairアリーナはNUMAに束縛されない
glibc malloc (current)NoPartialHighFairOS配置に依存
jemallocPartialYesMediumGoodオプションのNUMAアリーナチューニング
tcmallocLimitedYesMediumFairCPUキャッシュはNUMA対応ではない
mimallocNoYesLowVery Good強いスレッドローカリティ
HoardNoYesMediumGoodCPUごとのヒープが役立つ
nedmallocNoYesMediumFairスレッドキャッシュだがグローバルフォールバック
phkmallocPartialYesMediumFair初期ローカリティ最適化
libumemYesYesLowVery GoodSolaris NUMAポリシー
mtmallocYesYesLowVery GoodNUMA Solarisシステム向けに設計
snmallocYesYesVery LowExcellentNUMAファーストアーキテクチャ
lockless malloc (research)NoVariesHighPoorローカリティはほとんど考慮されない

ベンチマーク指向の実践的パフォーマンス

ベンチマーク指向の実践的パフォーマンス

アロケータ小オブジェクトスループット大オブジェクトスループット競合下でのレイテンシメモリオーバーヘッド断片化リスクメモ
dlmallocLowMediumPoorLowHighマルチスレッド負荷には不向き
ptmalloc2 / ptmalloc3MediumMediumPoorMediumMediumglibcデフォルト
glibc malloc (current)MediumMediumPoorMediumMediumチューニング可能だが限定的
jemallocHighHighVery GoodMedium-LowLow優れたオールラウンドアロケータ
tcmallocVery HighMediumGoodMediumMedium小オブジェクトに最適化
mimallocHighHighExcellentLowLow優れたレイテンシ予測可能性
HoardMediumMediumGoodMediumLowスケーラビリティのために設計
nedmallocMediumMediumFairMediumMedium古いが使用可能
phkmallocMediumMediumFairMediumMedium歴史的なFreeBSDアロケータ
libumemHighMediumVery GoodMediumLow強力なデバッグサポート
mtmallocHighMediumVery GoodMediumLowエンタープライズSolarisワークロード
snmallocHighHighExcellentLowVery Lowセキュリティ + スケーラビリティに注力
lockless malloc (research)VariesVariesPoorLowHigh実践では不安定なことが多い

アロケータ推奨

アロケータ推奨

ワークロードタイプ主なボトルネック主要リスク推奨アロケータ適した理由代替案回避
高度に競合するマルチスレッドアトミック/CASレイテンシキャッシュラインバウンスjemallocマルチアリーナ + スレッド親和性が共有CASを最小化mimallocsnmalloc,dlmalloc ptmalloc
低レイテンシ / テール感度割り当てジッターロックコンボイmimalloc非常に低いアトミック数と予測可能な高速パスsnmallocjemalloc,tcmalloc
NUMA / マルチソケットサーバーノード間メモリアクセスリモートキャッシュ所有権snmalloc明示的なNUMA対応とローカリティ制御jemalloc (NUMAチューニング済み)libumem,glibc malloc
小オブジェクト中心 (RPC / Web)アロケータスループット中央フリーリスト競合tcmallocCPUごとのキャッシュが小オブジェクト割り当てに最適化jemallocmimalloc,ptmalloc
大オブジェクト / 混合サイズ断片化TLB圧力jemalloc優れた断片化制御とエクステント管理mimallocglibc malloc
偽共有に敏感キャッシュラインのピンポンメタデータ共有Hoard偽共有を回避するように設計jemallocmimalloc,dlmalloc
セキュリティ強化使用後解放エクスプロイトヒープ破損snmalloc分離 + セキュリティ不変条件mimalloc (セキュア)ptmalloc
デバッグ / リーク検出メモリ誤用可視性サイレント破損libumem強力な実行時診断jemalloc (プロファイリング)tcmalloc
組み込み / 低メモリフットプリントサイズオーバーヘッドdlmallocシングルスレッドであれば小さくシンプルnedmallocjemalloc
リアルタイム / 決定論的無制限レイテンシOS干渉mimalloc低分散の高速パスsnmallocjemalloc,tcmalloc
HPC / 科学的NUMAメモリ帯域幅リモートNUMAヒットsnmallocNUMAファースト設計と低CASトラフィックjemalloc + mbindglibc malloc
レガシー / 互換性ABI安定性ツールチェーン問題glibc mallocシステムデフォルトで最も安全なフォールバックptmalloc

malloc選択のための意思決定チャート

[画像: malloc選択のための意思決定スーパートゥリー]

Graphviz DOTファイル

参考文献

  • R. J. Maher, Problems of storage allocation in a multiprocessor multiprogrammed system, Communications of the ACM, 4(10):421-422, October 1961

  • A fast storage allocator, Kenneth C. Knowlton, Communications of the ACM, 8(10):623-625, October 1965.

  • Statistical properties of the buddy system, P.W. Purdom and S. M. Stigler, Journal of the ACM, 17(4):683-697, October 1970

  • Statistical investigation of three storage allocation algorithms, P. W. Purdom, S. M. Stigler, and Tat-Ong Cheam, BIT, 11:187-195, 1971.

  • A note on an optimal-fit method for dynamic allocation of storage, J. A. Campbell, Computer Journal, 14(1):7-9, February 1971.

  • Worst-case analysis of memory allocation algorithms, M. R. Garey, R. L. Graham, and J. D. Ullman, In Fourth Annual ACM Symposium on the Theory of Computing, 1972

  • A class of dynamic memory allocation algorithms, D. S. Hirschberg, Communications of the ACM, 16(10):615-618, October 1973

  • Dynamic storage allocations of arbitrary sized segments, J. S. Fenton and D. W. Payne, In Proc. IFIPS, pages 344-348, 1974

  • Worst-case of Memory Allocation Algorithms, Garey 1972

  • A simplified recombination scheme for the Fibonacci buddy system, B. Cranston and R. Thomas, Communications of the ACM, 18(6):331-332, July 1975.

  • Buddy systems, J. L. Peterson and T. A. Norman, Communications of the ACM, 20(6):421-431, June 1977.

  • Worst case fragmentation of first fit and best fit storage allocation strategies, J. M. Robson, Computer Journal, 20(3):242-244, August 1977.

  • Fast-fit: A new hierarchical dynamic storage allocation technique, M. Tadman, Master’s thesis, UC Irvine, Computer Science Dept., 1978.

  • The double buddy-system, David S. Wise, Technical Report 79, Computer Science Department, Indiana University, Bloomington, Indiana, December 1978

  • Memory fragmentation in buddy methods for dynamic storage allocation, A. G. Bromley, Acta Informatica, 14(2):107-117, August 1980.

  • Optimal fit of arbitrary sized segments, Ivor P. Page, Computer Journal, 25(1), January 1982.

  • Parallelizing the usual buddy algorithm, A. Gottlieb and J. Wilson, Technical Report System Software Note 37, Courant Institute, New York University, 1982.

  • Fast fits: New methods for dynamic storage allocation, C. J. Stephenson, In Proceedings of the Ninth Symposium on Operating Systems Principles, pages 30-32, Bretton Woods, New Hampshire, October 1983. ACM Press. Published as Operating Systems Review 17(5), October 1983.

  • On the asymptotic optimality of first-fit storage allocation, E. G. Coffman, Jr., T. T. Kadota, and L. A. Shepp, IEEE Transactions on Software Engineering, SE-11(2):235-239, February 1985.

  • Efficient implementation of the first-fit strategy for dynamic storage alloca- tion, R. Brent, ACM Transactions on Programming Languages and Systems, July 1989.

  • Fast allocation and deallocation of memory based on object lifetimes, David R. Hanson, Software Practice and Experience, 20(1), January 1990.

  • Dynamic Storage Allocation: A Survey and Critical Review, very useful chronological order of malloc(), 1995

  • The Memory Fragmentation Problem: Solved? Johnstone 1997

  • A Memory Allocator, 2000

  • Solaris mtmalloc (archived), 2003

  • Anatomy of a Program in Memory, 2009

  • A History of malloc, 2010

  • Heap and allocators, 2015

  • Understanding glibc malloc

  • The Origins of Malloc, 2017

  • GrapheneOS hardened_malloc, 2019

  • Simulation of High-Performance Memory Allocators, Risco-Martin, 2024