Home>Article>Backend Development> In-depth understanding of Nginx memory management (picture)

In-depth understanding of Nginx memory management (picture)

不言
不言 forward
2018-11-15 17:14:53 3652browse

This article brings you an in-depth understanding of Nginx's memory management (picture). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

1. Overview

  1. The memory of the application can be simply divided into heap memory and stack memory. For stack memory, when a function is compiled, the compiler will insert code that moves the current pointer position of the stack to realize self-management of the stack space. For heap memory, programmers usually need to manage it. The memory management we usually talk about is only heap space memory management.

  2. For memory, our use can be simplified into three steps, applying for memory, using memory, and releasing memory. Applying for memory and using memory usually require explicit operations by programmers, but releasing memory does not necessarily require explicit operations by programmers. Currently, many high-level languages provide garbage collection mechanisms, and you can choose the time to release memory. For example: Go and Java have implemented garbage collection. Recycling, C language has not yet implemented garbage collection. Garbage collection can be achieved in C through smart pointers.

  3. In addition to language-level memory management, sometimes we need to manage memory by ourselves in the program. Generally speaking, for memory management, I think it is mainly to solve the following problems:

  • #When a user applies for memory, how to quickly find the memory block that meets the user's needs?

  • How to avoid memory fragmentation when users release memory?

Whether it is memory management implemented at the language level or memory management implemented by the application itself, memory is mostly divided into several types according to size, each using a different management mode. A common classification is to divide different types of memory into integer powers of 2 through linked lists. When querying, search from linked lists of corresponding sizes. If you cannot find it, you can consider taking a piece from a larger block of memory. , dividing it into multiple small points of memory. Of course, for particularly large memories, language-level memory management can directly call memory management-related system calls, and application-level memory management can directly use language-level memory management.

  1. nginx memory management as a whole can be divided into 2 parts,

  • The first part is the conventional memory pool, used For the memory management required by the process;

  • The second part is the management of shared memory. Overall, shared memory is much more complex than memory pools.

2. nginx memory pool management

2.1 Description

  1. The nginx version used in this part is 1.15.3

  2. For specific source code, please refer to the src/core/ngx_palloc.c file

2.2 nginx Implementation

2.2.1 Usage process

The use of nginx memory pool is relatively simple and can be divided into 3 steps,

  • Call the ngx_create_pool function Get the ngx_pool_t pointer.

//size代表ngx_pool_t一块的大小 ngx_pool_t* ngx_create_pool(size_t size, ngx_log_t *log)
  • Call ngx_palloc to apply for memory usage

//从pool中申请size大小的内存 void* ngx_palloc(ngx_pool_t *pool, size_t size)
  • Release memory (can release large blocks memory or release the entire memory pool)

//释放从pool中申请的大块内存 ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p) //释放整个内存池 void ngx_destroy_pool(ngx_pool_t *pool)

2.2.2 Specific implementation

  1. As shown in the figure below, nginx divides memory into two types, One is small memory and the other is large memory. When the applied space is larger than pool->max, we consider it to be large memory space, otherwise it is small memory space.

//创建内存池的参数size减去头部管理结构ngx_pool_t的大小 pool->max = size - sizeof(ngx_pool_t);

In-depth understanding of Nginx memory management (picture)

For a small memory space, nginx first checks whether the space to be allocated in the current memory block can meet the user's needs. If so, then Return this part of memory directly. If the user's needs cannot be met, you need to re-apply for a memory block. The applied-for memory block has the same size as the current block space. The newly-applied memory block is linked to the previous memory block through a linked list, and the user-required memory block is allocated from the new memory block. Memory.

Small memory is not released. The user can use it directly after applying. Even if it is no longer used later, there is no need to release the memory. Since users sometimes do not know whether the memory block they are using is large or small, they can also call the ngx_pfree function to release the space. This function will search for memory in the large space linked list and release the memory when it is found. For small memory, no processing is done.

For large blocks of memory, nginx will store them in linked lists and manage them through pool->large. It is worth noting that the ngx_pool_large_t structure for user-managed large memory is applied from a small block of memory in this memory pool, which means that these memories cannot be released. nginx directly reuses the ngx_pool_large_t structure. When the user needs to apply for a large memory space, use the c function library malloc to apply for the space, and then mount it on a certain ngx_pool_large_t structure. When nginx needs a new ngx_pool_large_t structure, it will first check the first three elements of the pool->large linked list to see if there is one available. If so, it will be used directly, otherwise it will create a new ngx_pool_large_t structure.

3. nginx shared memory management

3.1 Description

  1. The nginx version used in this part It is 1.15.3

  2. For details of the source code of this part, please see src/core/ngx_slab.c, src/core/ngx_shmtx.c

  3. ##nginx shared memory The content is relatively large, so this article only gives a brief overview.

3.2 Direct use of shared memory

3.2.1 Basics

  1. Need to create an interactive session in nginx Exclusion lock is used for synchronization of multiple processes later. In addition, nginx may need some statistical information, such as settings (stat_stub). We do not need to specially manage these variables. We only need to open the shared space and use them directly.

  2. The statistical information required after setting stat_stub is also placed in shared memory. We only use the mutex lock in nginx for explanation here.

3.2.2 Implementation of nginx mutex lock

  1. nginx mutex lock has two options. When the system supports atomic operations, Atomic operations are used, and file locks are used when not supported. See the ngx_event_module_init function for the source code of this section.

  2. The following figure is a schematic diagram of a file lock implementing a mutual exclusion lock.

In-depth understanding of Nginx memory management (picture)

  1. The following figure is a schematic diagram of atomic operation to implement a mutex lock.

In-depth understanding of Nginx memory management (picture)

  1. Problem

#When reloading, the newly started master The master exits directly after sending the signal. The old master reloads the configuration (ngx_init_cycle function) and creates a new worker process. The new worker process uses the same lock as the old worker process.

During smooth upgrade, the old master will create a new master, and the new master will inherit the listening port of the old master (the fd corresponding to the listening socket is passed through the environment variable), and the new process will not be restarted. Bind the listening port. There may be situations where new and old workers are listening to a certain port at the same time. In this case, the operating system will ensure that only one process handles the event (although epoll_wait will be awakened).

3.3 Manage shared memory through slab

  1. nginx allows each module to open up shared space for use, such as the ngx_http_limit_conn_module module.

  2. The basic ideas of nginx shared memory management are:

1. Allocate memory according to pages, and the size of each page is the same, here Set to page_size.

2. Divide the memory block according to the integer power of 2. The minimum is 8bit and the maximum is page_size/2. For example, assuming that the size of each page is 4Kb, the memory is divided into 9 types: 8, 16, 32, 64, 128, 256, 512, 1024, 2048, each corresponding to a slot. At this time, the size n of the slots array is 9. When applying for a small block of memory (applying for memory size size 3. Each page will only be divided into one type of memory block. For example, when applying for memory, the existing memory cannot meet the requirements. At this time, a new page will be used, and this new page will only allocate memory of this size in the future.

4. Connect all free pages through a doubly linked list. The free variable in ngx_slab_pool_t in the figure is used to link free pages.

5. Link the pages used by all small blocks of memory through the slots array.

6. For space requests greater than or equal to the page size, calculate the required number of pages, find continuous free pages, return the homepage address of the free page to the customer, and identify it through the management structure ngx_slab_page_t of each page.

7. All pages will only have 3 statuses: idle, not full, and full. Free and not-full pages are integrated through a two-way linked list. Full pages do not exist with any page. When the space is released, it will be added to a linked list.

  1. The basic structure diagram of nginx shared memory is as follows:

In-depth understanding of Nginx memory management (picture)

  • In the above figure, except for a section of memory starting from the ngx_slab_pool_t interface on the far right, which is located in the shared memory area, other memories are not shared memory.

  • Shared memory is ultimately allocated from page.

The above is the detailed content of In-depth understanding of Nginx memory management (picture). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete