之前一直理解的是buffer pool在启动时候就被分配好,今天有同事问到这个问题,跟着代码看了下。
buf_pool_init
|–>buf_pool_init_instance
|–>buf_chunk_init
|–>os_mem_alloc_large
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | OS_MAP_ANON, -1, 0);
调用mmap之前TOP出来的VIRT虚拟内存为135M,调用之后VIRT值为2714M,而实际的物理内存RES才不到100M
也就是说mmap并没有分配物理内存。
实际上这里使用mmap时限了匿名的存储区域映射,那么mmap和直接malloc有什么区别呢?
做个简单的实验
1.
#include <stdio.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys/mman.h>
int main(int argc, char *argv[])
{
printf(“alloc=====\n”);
char *ptr = malloc(2693120000); //2.5G
sleep(60);
free(ptr);
printf(“=====finish\n”);
return 0;
}
2.
将内存分配修改为:
void* ptr= mmap(0, 2693120000, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_SHARED, -1 , 0);
看起来不管是malloc,还是mmap,都没有分配实际的物理地址,仅仅是分配了虚拟内存。
那么什么时候才会分配内存呢?mysqld拿到的只是映射自物理内存的一块虚拟内存,只有在应用程序真正使用到内存时才会去映射到实际的物理内存。这些工作都是由内核来完成的