Hacker News

最初の C++ (m) 割り当てが常に 72 KB になるのはなぜですか?

最初の C++ メモリ割り当てが予期されたバイトではなく 72 KB を要求する理由を確認してください。 malloc の内部構造と OS メモリ管理層について説明します。

1 最小読み取り

Mewayz Team

Editorial Team

Hacker News

初めての C++ 割り当ての背後にある謎

簡単な C++ プログラムを作成します。単一の新しい int。 4バイト。 strace またはお気に入りのメモリ プロファイラを起動すると、プロセスがオペレーティング システムから約 72 KB を要求したことがわかります。 4バイトではありません。 64バイトではありません。完全な 72 KB。この数字を見つめて、自分のツールが嘘をついているのではないかと疑問に思ったことがあるのは、あなただけではありません。この一見奇妙に見える動作は、メモリの内部を初めて調査する C++ 開発者の間で最もよく寄せられる質問の 1 つであり、その答えは、コードと実際のハードウェアの間にある層を巡る興味深い旅へと私たちを導きます。

新しい電話をかけるとどうなるか

72 KB という数字を理解するには、割り当てチェーン全体を追跡する必要があります。 C++ コードが new int を実行すると、コンパイラはそれを演算子 new の呼び出しに変換します。ほとんどの Linux システムでは、この演算子は glibc から malloc に委任されます。ただし、malloc はカーネルに 4 バイトのメモリを直接要求しません。カーネルはページ単位 (x86_64 では通常 4 KB) で動作し、システム コールのコストは単純なメモリ アクセスに比べて膨大です。個々の割り当てごとに brk() または mmap() を呼び出すと、重要なプログラムは停止してしまいます。

代わりに、glibc のメモリ アロケータ (ptmalloc2 と呼ばれる実装であり、それ自体が Doug Lea の古典的な dlmalloc から派生したもの) が仲介者として機能します。カーネルに大きなメモリ ブロックを事前に要求し、プログラムが必要とするときにそれらをより小さな部分に分割します。これが、最初の 4 バイトの割り当てによってオペレーティング システムに対するはるかに大きなリクエストがトリガーされる根本的な理由です。アロケーターは無駄ではありません。それは戦略的です。

72 KB を分析する: バイトの行き先

初期割り当てのオーバーヘッドは、使用可能なメモリを 1 バイトでも渡す前に、ランタイムが初期化する必要があるいくつかの異なるコンポーネントから発生します。各構成要素を理解すると、その数字がなぜその位置に着くのかがわかります。

まず、glibc の malloc はメイン アリーナ (メイン スレッド上のすべての割り当てを追跡する主要な簿記構造) を初期化します。この領域には、ヒープのメタデータ、フリーリスト ポインター、およびさまざまな割り当てサイズのビン構造が含まれます。アロケータは sbrk() を介してプログラム ブレークを拡張し、初期拡張は M_TOP_PAD と呼ばれる内部パラメータによって制御されます。このパラメータのデフォルトは 128 KB のパディングです。ただし、実際の最初のリクエストは、ページの配置と既存のブレーク位置に合わせて調整されるため、多くの場合、最初のリクエストは小さくなり、新しく開始されたプロセスでは通常、その 72 KB の数値近くになります。

💡 ご存知でしたか?

Mewayzは8つ以上のビジネスツールを1つのプラットフォームに統合します

CRM・請求・人事・プロジェクト・予約・eCommerce・POS・分析。永久無料プラン提供中。

無料で始める →

次に、glibc 2.26 以降、アロケータは最初の使用時にスレッドローカル キャッシュ (tcache) を初期化します。 tcache には 64 個のビン (小さい割り当てサイズのクラスごとに 1 つ) が含まれており、それぞれが最大 7 つのキャッシュされたチャンクを保持できます。 tcache_perthread_struct 自体は約 1 KB を消費しますが、それを初期化する行為により、より広範なアリーナのセットアップがトリガーされます。 3 番目に、C++ ランタイムは、main() が実行される前に既に割り当てを実行しています。静的コンストラクター、std::cout およびその仲間の iostream バッファーの初期化、およびロケールのセットアップはすべて、初期ヒープ フットプリントに貢献します。

アリーナ システムと事前割り当てが賢明な理由

メモリを少しずつ要求するのではなく、かなりの量のメモリを事前に割り当てるという決定は、実装上の偶然ではありません。これは、数十年にわたるシステム プログラミングの経験に根ざした、意図的なエンジニアリングのトレードオフです。 brk() または mmap() へのすべての呼び出しには、ユーザー空間からカーネル空間へのコンテキストの切り替え、プロセスの仮想メモリ マッピングの変更、および潜在的なページ テーブルの更新が含まれます。最新のハードウェアでは、1 回のシステム コールにおよそ 100 ~ 200 ナノ秒のコストがかかります。これは、単独ではわずかですが、規模が大きくなると壊滅的です。

初期化中に 10,000 の小さな割り当てを行うプログラムを考えてみましょう。事前割り当てがなければ、10,000 回のシステムコールが発生し、純粋なオーバーヘッドとして約 1 ~ 2 ミリ秒のコストがかかります。アリーナベースのアロケータでは、最初の割り当てトリガー

Build Your Business OS Today

From freelancers to agencies, Mewayz powers 138,000+ businesses with 207 integrated modules. Start free, upgrade when you grow.

Create Free Account →

Frequently Asked Questions

なぜ最初の `new` 呼び出しで malloc は 72 KB も確保するのですか?

これは、メモリ割り当ての効率化のためです。カーネルへのシステムコール(例: `mmap`)は高コストであるため、メモリ管理ライブラリ(glibc の malloc など)は、小さな要求を受けても、将来の要求に備えて大きなメモリブロック(この場合は約 64 KB + 管理用のオーバーヘッドで合計 72 KB)を一度にカーネルから取得します。これにより、プログラムが続けて小さな割り当てを行う際に、システムコールの回数を減らすことができます。

この 72 KB の領域は具体的には何に使われますか?

72 KB のうち、ユーザーが要求した 4 バイトはほんの一部です。残りの大部分は、「アリーナ」や「ヒープ」と呼ばれるプールとして確保され、プログラムが次に行う可能性のある `new` や `malloc` の呼び出しにすぐに利用できるようにします。また、このメモリブロックの管理情報(サイズや使用状況を追跡するメタデータ)を格納するためのオーバーヘッドも含まれています。

この動作は OS やアーキテクチャによって変わりますか?

はい、変わります。72 KB という値は、x86_64 アーキテクチャの Linux における glibc の特定のバージョンでの典型的な例です。異なるオペレーティングシステム(Windows など)や異なるメモリアロケータを使用した場合、この初期サイズは異なる可能性があります。メモリの詳細な分析には、Mewayz のようなプロファイリングツール(207のモジュールを月額$19で提供)を使用すると、特定の環境での動作を正確に把握できます。

この知識はメモリ効率の良いプログラムを書く上でどのように役立ちますか?

メモリ割り当ての内部動作を理解することで、パフォーマンスのボトルネックを特定するのに役立ちます。例えば、多数の小さなオブジェクトを絶えず作成・破棄するコードは、予想以上に多くのメモリを消費したり、断片化を引き起こしたりする可能性があります。このような場合、メモリプールやカスタムアロケータの使用を検討することで、オーバーヘッドを削減できます。Mewayz のモジュールを使用すれば、メモリ割り当てパターンを可視化し、最適化の機会を見つけることができます。

Mewayzを無料で試す

CRM、請求書、プロジェクト、人事などを網羅するオールインワンプラットフォーム。クレジットカードは不要です。

今日からビジネス管理をスマートに始めましょう。

30,000+社の企業が参加しています。永久無料プラン・クレジットカード不要。

これは役に立ちましたか?共有する。

実践に移す準備はできていますか?

Join 30,000+ businesses using Mewayz. Free forever plan — no credit card required.

無料トライアル開始 →

行動を起こす準備はできていますか?

今日からMewayz無料トライアルを開始

オールインワンビジネスプラットフォーム。クレジットカード不要。

無料で始める →

14日間無料トライアル · クレジットカード不要 · いつでもキャンセル可能