Speicherpoolfunktion:
ngx_create_pool ngx_destroy_pool ngx_reset_pool ngx_palloc ngx_pnalloc ngx_palloc_block ngx_palloc_large ngx_pool_cleanup_add
Speicherpoolerstellung
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; }
Die Initialisierungsstruktur ist wie folgt:
Die grüne Linie stellt das Strukturmitglied dar. Zu den Mitgliedern von ngx_pool_data_t gehören beispielsweise last, end, next, failed
Die schwarze Linie stellt die Adresse dar, auf die der Zeiger zeigt
1 max wird für size-sizeof(ngx_pool_t) und 4095 erstellt, wählen Sie das kleinste
2 Protokoll aus und rufen Sie die von ngx_log_init in main erstellte ngx_log_t-Struktur auf (dh das globale ngx_log-Objekt)
Prinzip :
nginx beginnt tatsächlich bei d.last. Da der Speicherpoolbereich extern zugewiesen wird, verschiebt sich die Ausrichtung dieses Felds nach hinten >Speicherpoolzuweisung
ngx_palloc () Versuchen Sie, Speicherplatz der Größe size aus dem Poolspeicherpool zuzuweisen. Es gibt zwei Situationen.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); }
Wenn im ersten Fall die zugewiesene Größe kleiner als ngx_pool_t.max ist (kleine Blockzuweisung, Code 127-140), müssen Sie zuerst die letzten 16 Bits ausrichten, sofern noch Platz in der Anwendung vorhanden ist , dann verwenden Sie diesen Speicherknoten (d. h. Code 130). Bewegen Sie sich gleichzeitig als letzter, um auf die zugewiesene Adresse zu zeigen, und geben Sie den angeforderten Speicher an den Aufrufer zurück, wenn beim Durchlaufen der kleinen Speicherknoten kein Speicherplatz zugewiesen werden kann aktuell (d. h. Durchlaufen der verknüpften Liste, bis der nächste Speicherpoolknoten leer ist). Sie müssen einen Speicherpoolknoten zuweisen und ngx_palloc_block(pool,size) aufrufen
Diese Funktion weist hauptsächlich einen Speicherpoolknoten zu, fügt diesen Knoten dann am Ende der verknüpften Liste ein und aktualisiert den Pool-> Der aktuelle Zeiger wird gleichzeitig durchquert. Wenn in der verknüpften Liste festgestellt wird, dass dieser Knoten sechsmal nicht zugewiesen werden konnte, zeigt der aktuelle Zeiger auf den nächsten Knoten. current zeigt auf den neu zugewiesenen Knoten.
Der Kerncode lautet wie folgt:
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
Rückruffunktion löschen
wobei jeder Knoten
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; }