為什么需要內存分配器
系統的物理內存是有限的,而對內存的需求是變化的, 程序的動態性越強,內存管理就越重要,選擇合適的內存管理算法會帶來明顯的性能提升。
比如nginx, 它在每個連接accept后會malloc一塊內存,作為整個連接生命周期內的內存池。 當HTTP請求到達的時候,又會malloc一塊當前請求階段的內存池, 因此對malloc的分配速度有一定的依賴關系。(而apache的內存池是有父子關系的,請求階段的內存池會和連接階段的使用相同的分配器,如果連接內存池釋放則請求階段的子內存池也會自動釋放)。
內存分配如果分配不好就會浪費了大量空間,導致產生內存碎片(Memory Fragmentation),這些內存碎片是在系統中不可使用的空閑內存,因為內存分配器不能把這些內存分配使用雖然有大量零散的可用空間,卻無法合並提供出來使用。
所以使用內存分配器就是為了更加高效地更加安全地利用內存。
malloc和free
通常我們所知道使用的內存分配器,即malloc()/free()函數並不是系統提供的,而是C標准庫提供的,也被稱為動態內存分配器。分配器從操作系統拿內存(虛擬內存)時是以頁為單位(通常是4KB,調用sbrk或mmap), 然后再自行管理。
這兩個函數的作用分別:
malloc是申請一段內存空間,free就是釋放指定的內存空間。
1. malloc()
malloc函數的函數原型為:void* malloc(unsigned int size),它根據參數指定的尺寸來分配內存塊,並且返回一個void型指針,指向新分配的內存塊的初始位置。如果內存分配失敗(內存不足),則函數返回null。
申請內存,確認是否申請成功:
char *str = (char*) malloc(100); assert(str != nullptr);
2. free()
free函數的函數原型為:free(void* pointer)。free函數中的參數必須要不為空,不然就必須是malloc,calloc,realloc中返回值。
釋放內存后指針置空:
free(p); p = nullptr;