この記事は、Nginx のメモリ管理 (写真) についての深い理解をもたらします。一定の参考価値があります。必要な友人は参照できます。お役に立てば幸いです。
1. 概要
アプリケーションのメモリは、単純にヒープ メモリとスタック メモリに分けることができます。スタック メモリの場合、関数がコンパイルされると、コンパイラはスタック領域の自己管理を実現するためにスタックの現在のポインタ位置を移動するコードを挿入します。ヒープ メモリの場合、通常はプログラマが管理する必要があります。私たちが通常話しているメモリ管理は、ヒープ領域のメモリ管理のみです。
メモリの使用は、メモリの適用、メモリの使用、メモリの解放の 3 つのステップに単純化できます。通常、メモリの申請やメモリの使用にはプログラマによる明示的な操作が必要ですが、メモリの解放には必ずしもプログラマによる明示的な操作が必要ではありません。現在、多くの高級言語ではガベージ コレクションのメカニズムが提供されており、メモリを解放するタイミングを選択できます。例: Go と Java はガベージ コレクションを実装していますが、リサイクル、C 言語はまだガベージ コレクションを実装していませんが、ガベージ コレクションはスマート ポインタを使用して C で実現できます。
言語レベルのメモリ管理に加えて、プログラム内で独自にメモリ管理を行う必要がある場合がありますが、一般的にメモリ管理では主に以下の問題を解決することが多いと思います。 :
#ユーザーがメモリを申請するとき、ユーザーのニーズを満たすメモリ ブロックを素早く見つけるにはどうすればよいでしょうか?
ユーザーがメモリを解放するときにメモリの断片化を回避するにはどうすればよいでしょうか?
言語レベルで実装されるメモリ管理であっても、アプリケーション自体によって実装されるメモリ管理であっても、メモリはほとんどの場合、サイズに応じていくつかのタイプに分類され、それぞれ異なる管理モードが使用されます。一般的な分類は、リンク リストを使用して、さまざまな種類のメモリを 2 の整数乗に分割することです。クエリを実行するときは、対応するサイズのリンク リストから検索します。見つからない場合は、より大きなメモリ ブロックから一部を取得することを検討できます。それを複数の小さな記憶ポイントに分割します。もちろん、特に大きなメモリの場合、言語レベルのメモリ管理はメモリ管理関連のシステム コールを直接呼び出すことができ、アプリケーション レベルのメモリ管理は言語レベルのメモリ管理を直接使用できます。
nginx のメモリ管理は全体として 2 つの部分に分けることができます。
最初の部分はコンベンショナル メモリです。プール、プロセスで必要なメモリ管理に使用;
2 番目の部分は共有メモリの管理です。全体として、共有メモリはメモリ プールよりもはるかに複雑です。
#2. nginx メモリ プール管理
2.1 説明
2.2 nginx の実装
2.2.1 使用プロセスnginx メモリ プールの使用は比較的単純で、3 つのステップに分けることができます。//size代表ngx_pool_t一块的大小 ngx_pool_t* ngx_create_pool(size_t size, ngx_log_t *log)
//从pool中申请size大小的内存 void* ngx_palloc(ngx_pool_t *pool, size_t size)
//释放从pool中申请的大块内存 ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p) //释放整个内存池 void ngx_destroy_pool(ngx_pool_t *pool)
//创建内存池的参数size减去头部管理结构ngx_pool_t的大小 pool->max = size - sizeof(ngx_pool_t);
大きなメモリ ブロックの場合、nginx はそれらをリンク リストに保存し、pool->large を通じて管理します。ユーザー管理の大きなメモリの ngx_pool_large_t 構造は、このメモリ プール内の小さなメモリ ブロックから適用されるため、これらのメモリを解放できないことは注目に値します。nginx は ngx_pool_large_t 構造を直接再利用します。ユーザーが大きなメモリ空間を申請する必要がある場合、C 関数ライブラリ malloc を使用して領域を申請し、それを特定の ngx_pool_large_t 構造体にマウントします。 nginx が新しい ngx_pool_large_t 構造体を必要とする場合、最初にプール -> ラージ リンク リストの最初の 3 つの要素をチェックして、利用可能なものが存在するかどうかを確認し、利用可能な場合は直接使用され、そうでない場合は新しい ngx_pool_large_t 構造体が作成されます。
3. nginx 共有メモリ管理
3.1 説明
この中で使用される nginx のバージョン部分 1.15.3
この部分のソースコードの詳細については、src/core/ngx_slab.c、src/core/ngx_shmtx.c
3.2 共有メモリの直接使用
3.2.1 基本#問題
#リロードすると、新しく起動したマスターがマスターシグナル送信後すぐに終了します。古いマスターは設定 (ngx_init_cycle 関数) をリロードし、新しいワーカー プロセスを作成します。新しいワーカー プロセスは、古いワーカー プロセスと同じロックを使用します。
nginx を使用すると、ngx_http_limit_conn_module モジュールなどの各モジュールが使用する共有スペースを開くことができます。
nginx 共有メモリ管理の基本的な考え方は次のとおりです:
1. ページに従ってメモリを割り当て、各ページのサイズは同様に、ここでは page_size に設定します。
3. 各ページは 1 種類のメモリ ブロックにのみ分割されます。たとえば、メモリを申請する場合、既存のメモリでは要件を満たせない場合、新しいページが使用され、今後この新しいページにはこのサイズのメモリのみが割り当てられます。
4. 二重リンクリストを介してすべてのフリーページを接続します。図のngx_slab_pool_tのfree変数はフリーページのリンクに使用されます。
5. スロット配列を介して、メモリのすべての小さなブロックで使用されるページをリンクします。
6. ページサイズ以上のスペースリクエストの場合は、必要なページ数を計算し、連続した空きページを見つけ、その空きページのホームページアドレスをお客様に返信し、管理を通じて特定します。各ページの構造体 ngx_slab_page_t 。
7. すべてのページには、アイドル状態、フルではない、フルの 3 つのステータスのみがあります。フリー ページとフル ページ以外のページは、双方向のリンク リストによって統合されます。フル ページはどのページにも存在しません。スペースが解放されると、リンク リストに追加されます。
nginx 共有メモリの基本構造図は次のとおりです。
上図では、共有メモリ領域にある、右端の ngx_slab_pool_t インターフェイスから始まるメモリ セクションを除き、他のメモリは共有メモリではありません。
共有メモリは最終的にページから割り当てられます。
以上がNginx のメモリ管理についての深い理解 (写真)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。