ホームページ バックエンド開発 PHPチュートリアル [nginxソースコード解析]ngxメモリプール実装

[nginxソースコード解析]ngxメモリプール実装

Aug 08, 2016 am 09:24 AM
current gt pool size

メモリプール関数:

ngx_create_pool
ngx_destroy_pool
ngx_reset_pool
ngx_palloc
ngx_pnalloc
ngx_palloc_block
ngx_palloc_large
ngx_pool_cleanup_add
ログイン後にコピー

メモリプールの作成

ngx_pool_t *
  ngx_create_pool(size_t size, ngx_log_t *log)
  {
      ngx_pool_t  *p;
  
      p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);//按照16字节对齐分配一块size大小内存
      if (p == NULL) {
          return NULL;
      }                                                                                                                                                              
  
      p->d.last = (u_char *) p + sizeof(ngx_pool_t);  //last指向数据部分开始(跳过header ngx_pool_t)结构
      p->d.end = (u_char *) p + size;                 //end指向末尾结构
      p->d.next = NULL;                               //next是对小块内存链表管理指针
      p->d.failed = 0;                                //此块内存分配失败次数
  
      size = size - sizeof(ngx_pool_t);               //去掉ngx_pool_t内存池的实际大小
      p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;//最大内存池节点大小为4095
  
      p->current = p;                                 //current指向p
      p->chain = NULL;
      p->large = NULL;
      p->cleanup = NULL;
      p->log = log;
  
      return p;
  }
ログイン後にコピー

初期化構造体は以下のとおりです:

緑色の線は構造体のメンバーを示します。たとえば、ngx_pool_data_tのメンバーにはlast、end、next、失敗しました

黒い線はポインタが指すアドレスを表します

1 maxはsize-sizeof(ngx_pool_t)と4095の間で最小のものを選択します

2 logはmainのngx_log_initによって作成されたngx_log_t構造体(つまり、グローバルngx_log)を呼び出しますオブジェクト)

原則:

nginx が実際にこのメモリ プールから領域を割り当てる開始位置は、d.last から始まります。

void *
 ngx_palloc(ngx_pool_t *pool, size_t size)
 {  
     u_char      *m;
     ngx_pool_t  *p;       
 
     //如果申请的内存大小小于创建的内存池节点大小(当然是去掉ngx_pool_t后)
     if (size <= pool->max) {
 
         p = pool->current;
 
         do {
             m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);//首先对齐last指针
 
             if ((size_t) (p->d.end - m) >= size) {
                 p->d.last = m + size;          
 
                 return m;
             }
 
             p = p->d.next;
 
         } while (p);
 
         return ngx_palloc_block(pool, size);
     }                                                                                                                                                              
 
     return ngx_palloc_large(pool, size);
 }
ログイン後にコピー
ngx_palloc() は、プール メモリからスペースを割り当てようとします。 プールにサイズ size のスペースを割り当てる場合、2 つの状況があります。

最初のケースでは、割り当てられたサイズが ngx_pool_t.max (小さいブロック割り当て、コード 127-140) より小さい場合、最初に最後の 16 ビットを整列する必要があります。アプリケーションにまだスペースがある場合は、これを使用します。メモリ ノード (コード 130) ) は、同時に最後に割り当てられたアドレスをポイントするように移動し、現在のメモリ ノード (つまり、次のメモリ プール ノードが空になるまでリンク リストを走査します)。メモリ プール ノードを割り当てて、ngx_palloc_block(pool,size) を呼び出す必要があります

この関数は主にメモリ プール ノードを割り当て、このノードをリンク リストの最後に挿入し、同時に pool->current ポインタを更新します更新アルゴリズムは、このノードの割り当てが 6 回失敗した場合、現在のノードを参照します。新しく割り当てられたノード。

コアのコードは次のとおりです:

current = pool->current;//初始化
 
     for (p = current; p->d.next; p = p->d.next) {//遍历
         if (p->d.failed++ > 4) {//分配超过6次
             current = p->d.next;
         }
     }
 
     p->d.next = new;//插入新节点                                                                                                                          
 
     pool->current = current ? current : new;//更新current
ログイン後にコピー

2 番目のケースでは、大きなメモリを割り当て、割り当て後、大きなリンク リストがある場合は、malloc を呼び出します。メモリ プール ノードがあり、alloc が空の場合、このノードに新しく割り当てられたメモリをハングします。そのようなノードがない場合は、p->large のリンク リストの先頭を割り当てて挿入します。
コールバック関数のクリア

各ノードの場所

 struct ngx_pool_cleanup_s {
      ngx_pool_cleanup_pt   handler;//回调handler
      void                 *data;	//回调函数参数
      ngx_pool_cleanup_t   *next;	//指向下一个节点
  };
ログイン後にコピー
ngx_pool_cleanup_t *      
 ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
 {
     ngx_pool_cleanup_t  *c;
    
     c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));//分配一个节点
     if (c == NULL) {      
         return NULL;
     }
 
     if (size) {
         c->data = ngx_palloc(p, size); 
         if (c->data == NULL) {
             return NULL;
         }
 
     } else {
         c->data = NULL;
     }
 
     c->handler = NULL;
     c->next = p->cleanup;//插入链表头
 
     p->cleanup = c;//插入链表头部
 
     ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);
 
     return c;                                                                                                                                                      
 }
ログイン後にコピー

以上、[nginx ソースコード解析] ngx メモリプールの実装を内容も含めて紹介しましたが、PHP チュートリアルに興味のある友人の参考になれば幸いです。


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Huawei GT3 ProとGT4の違いは何ですか? Huawei GT3 ProとGT4の違いは何ですか? Dec 29, 2023 pm 02:27 PM

多くのユーザーはスマートウォッチを選ぶときにファーウェイブランドを選択しますが、その中でもファーウェイ GT3pro と GT4 は非常に人気のある選択肢であり、多くのユーザーはファーウェイ GT3pro と GT4 の違いに興味を持っています。 Huawei GT3pro と GT4 の違いは何ですか? 1. 外観 GT4: 46mm と 41mm、材質はガラスミラー + ステンレススチールボディ + 高解像度ファイバーバックシェルです。 GT3pro: 46.6mm および 42.9mm、材質はサファイアガラス + チタンボディ/セラミックボディ + セラミックバックシェルです。 2. 健全な GT4: 最新の Huawei Truseen5.5+ アルゴリズムを使用すると、結果はより正確になります。 GT3pro: ECG 心電図と血管と安全性を追加

JavaのFile.length()関数を使用してファイルのサイズを取得します。 JavaのFile.length()関数を使用してファイルのサイズを取得します。 Jul 24, 2023 am 08:36 AM

ファイルのサイズを取得するには、Java の File.length() 関数を使用します。ファイル操作を扱うとき、ファイル サイズは非常に一般的な要件です。Java では、ファイルのサイズを取得するための非常に便利な方法、つまり length( ) File クラスのメソッド。この記事では、このメソッドを使用してファイルのサイズを取得する方法と、対応するコード例を紹介します。まず、サイズを取得したいファイルを表す File オブジェクトを作成する必要があります。 File オブジェクトを作成する方法は次のとおりです: Filef

修正: Windows 11 で Snipping ツールが機能しない 修正: Windows 11 で Snipping ツールが機能しない Aug 24, 2023 am 09:48 AM

Windows 11 で Snipping Tool が機能しない理由 問題の根本原因を理解すると、適切な解決策を見つけるのに役立ちます。 Snipping Tool が正しく動作しない主な理由は次のとおりです。 フォーカス アシスタントがオンになっている: これにより、Snipping Tool が開かなくなります。破損したアプリケーション: 起動時にスニッピング ツールがクラッシュする場合は、破損している可能性があります。古いグラフィック ドライバー: 互換性のないドライバーは、スニッピング ツールに干渉する可能性があります。他のアプリケーションからの干渉: 実行中の他のアプリケーションが Snipping Tool と競合する可能性があります。証明書の有効期限が切れています: アップグレード プロセス中のエラーにより、この問題が発生する可能性があります。これらの簡単な解決策は、ほとんどのユーザーに適しており、特別な技術知識は必要ありません。 1. Windows および Microsoft Store アプリを更新する

iPhoneでApp Storeに接続できないエラーを修正する方法 iPhoneでApp Storeに接続できないエラーを修正する方法 Jul 29, 2023 am 08:22 AM

パート 1: 最初のトラブルシューティング手順 Apple のシステムステータスを確認する: 複雑な解決策を掘り下げる前に、基本から始めましょう。問題はデバイスにあるのではなく、Apple のサーバーがダウンしている可能性があります。 Apple のシステム ステータス ページにアクセスして、AppStore が適切に動作しているかどうかを確認してください。問題があれば、Apple が修正してくれるのを待つしかありません。インターネット接続を確認します。「AppStore に接続できません」問題は接続不良が原因である場合があるため、安定したインターネット接続があることを確認してください。 Wi-Fi とモバイル データを切り替えるか、ネットワーク設定をリセットしてみてください ([一般] > [リセット] > [ネットワーク設定のリセット] > [設定])。 iOS バージョンを更新します。

php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 Jun 13, 2016 am 10:23 AM

php提交表单通过后,弹出的对话框怎样在当前页弹出php提交表单通过后,弹出的对话框怎样在当前页弹出而不是在空白页弹出?想实现这样的效果:而不是空白页弹出:------解决方案--------------------如果你的验证用PHP在后端,那么就用Ajax;仅供参考:HTML code

TreeSet クラスの size() メソッドを使用して、ツリー コレクション内の要素の数を取得します。 TreeSet クラスの size() メソッドを使用して、ツリー コレクション内の要素の数を取得します。 Jul 24, 2023 am 11:05 AM

タイトル: TreeSet クラスの size() メソッドを使用して、ツリー コレクション内の要素の数を取得します。はじめに TreeSet は、Java コレクション フレームワークの順序付きコレクションです。SortedSet インターフェイスを実装し、赤黒ツリー データ構造を使用して、それを実装します。 TreeSet は、要素の自然な順序に従って、または Comparator カスタム コンパレータを使用して並べ替えることができます。この記事では、TreeSet クラスの size() メソッドを使用して、ツリー コレクション内の要素の数を取得し、提供する方法を紹介します。

watch4proとGTのどちらが優れていますか? watch4proとGTのどちらが優れていますか? Sep 26, 2023 pm 02:45 PM

Watch4proとgtはそれぞれ特徴や適用シーンが異なりますが、総合的な機能、高性能、スタイリッシュな外観を重視し、価格は高くてもいいという方にはWatch 4 Proの方が適しているかもしれません。高度な機能要件はなく、バッテリー寿命と手頃な価格を重視する場合は、GT シリーズの方が適しているかもしれません。最終的な選択は、個人のニーズ、予算、好みに基づいて決定する必要がありますが、購入する前に自分のニーズを慎重に検討し、さまざまな製品のレビューや比較を参照して、より情報に基づいた選択を行うことをお勧めします。

Linux システム上の MySQL データベースのパフォーマンスの最適化に関する詳細なチュートリアル。 Linux システム上の MySQL データベースのパフォーマンスの最適化に関する詳細なチュートリアル。 Feb 19, 2024 pm 05:51 PM

以下は、Linux システムでの MySQL データベースのパフォーマンスの最適化に関する詳細なチュートリアルです。 構成ファイルの最適化: MySQL 構成ファイル (通常は my.cnf または my.ini) を開きます。パフォーマンスを最適化するには、次のパラメータを調整します。 key_buffer_size: データのサイズに合わせてインデックス キャッシュ サイズを調整します。 innodb_buffer_pool_size: データ サイズに合わせて InnoDB バッファー プール サイズを調整します。 innodb_log_file_size: 書き込み負荷に合わせて InnoDB ログ ファイル サイズを調整します。 query_cache_size: クエリ キャッシュを有効にしてサイズ変更します。最大接続数

See all articles