Пятница, 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(тип_вашего_указателя) и эта память будет использоваться повторно ☺

Написано в: 0:55 | 0 комментариев | | теги: , , , , , | постоянная ссылка |
Добавить пост в:   Delicious Reddit Slashdot Digg Technorati Google


Последние комментарии

Пингбэки

catap's blog ~ nginx programming guide: работа с памятью @catap.ru 18.04.2008 11:55
Что бы закончить про «память» в nginx надо затронуть тему выделения памяти из pool’а.

Комментарии

К этой публикации комментариев нет

Форма комментирования для «nginx programming guide: pool'ы памяти»

Обязательное поле. Не больше 30 символов.

Обязательное поле