Пятница, 18 Апрель 2008
nginx programming guide: pool’ы памяти
Nginx это достаточно сложная программа, в которой есть свои методы работы с памятью, о которых хочется рассказать. Но начинать стоит с малого. С pool’ов.
Общие сведения
В Nginx не рекомендуется вызывать malloc/free в своих модулях, для выделения памяти лучше использовать ngx_palloc/ngx_pcalloc. Как ее освобождать? Никак. Она освобождается автоматически, точнее освобождается всем pool’ом памяти (дальше pool).
В nginx pool памяти это структура:
struct ngx_pool_s {
u_char *last;
u_char *end;
ngx_pool_t *current;
ngx_chain_t *chain;
ngx_pool_t *next;
ngx_pool_large_t *large;
ngx_pool_cleanup_t *cleanup;
ngx_log_t *log;
};
Здесь:
- last — указатель на конец выделенной памяти из пула
- end — указатель на конец доступной памяти в пуле
- current — указатель на текущий pool
- chain — указатель на выделенные chain’ы из этого pool’а
- next — указатель на следующий pool, связанный с этим
- large — список больших кусков памяти
- cleanup — handler’ы для очистки
- log — указатель на log файл
Создание
Новый pool можно создать используя команду:
ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);
Из аргументов, на первый взгляд, все понятно. log — это указатель на log файл, тут все просто, а вот с size есть небольшой нюанс: создать pool размера меньшем чем sizeof(ngx_pool_t) у вас не получится. Т.е. получится но скорее всего будет сегфол ☺
Причина простая: pool это большой кусок памяти, размера size, в начале которого идет ngx_pool_t, а за ним… та память на которую указывают last и end. Т.е. удалить pool просто, надо сделать ngx_free(pool) ☺
Удаление
Удалить pool через ngx_free можно, но это не совсем корректно. Т.к. мы не освободим связанные с нашем pool’ом pool’ы. Для корректного удаления стоит использовать функцию:
void ngx_destroy_pool(ngx_pool_t *pool);
Логика работы простая. В начале проходим по всем cleanup handler’ам, до тех пора пока cleanup->next не будет NULL, запуская cleanup->handler(cleanup->data). Потом освобождаем large, проверяя что он выделен (large->alloc). И последняя стадия это освобождение pool’ов. С освобождение pool’ов есть небольшая хитрость: в next pool’ах используются только last и end.
Хитрости
Интересная хитрость, заключается в том, что если вам память больше не нужна и она была последней выделенной (ваш_указатель + sizeof(тип_вашего_указателя) == pool->last) то можно сделать pool->last -= sizeof(тип_вашего_указателя) и эта память будет использоваться повторно ☺
Комментарии
Форма комментирования для «nginx programming guide: pool'ы памяти»