PHP7在内存管理上使用了全新的方法,其性能提高也有大部分得益于这个变化。
PHP7的内存管理策略主要借鉴自 jemalloc and tcmalloc,具体来说:
所有的内存分配任务被分为了三大类:
1、 Huge:程序请求的内存大小如果超过了一个块( CHUNK)的大小,默认是 2M。这种情况下会直接使用 mmap 系统调用从操作系统直接“批发”,“批发”到的内存都是CHUNK的整数倍。这也是大多数的内存分配算法采用的策略;
2、Large:一个块中会有大量的页,一页的大小是4K;对于此类请求,分配的都是页的倍数;
3、Small:如果程序申请的内存小于 3/4 个页的大小,会分配距离预定义的 small size 最近的内存大小(一共有30个预定的 small size:8, 16, 24 ,32,……3072)。相同大小的small size会组成一个链表:RUN。此类请求就是从RUNs中找到下一个空闲位置,分配给用户。
每一个块的第一页都不分配,而是作为块的头信息保留下来,其中记录了:
free_pages 空闲页的总数;
free_tails 块尾连续空闲页的数量;
free_map 位图。每一页一位,如果这一页被分配了,这一位将会被标记为1。分配Large内存的时候,只要找到连续的0位就可以了;
map 图。包括每一页的信息。(一页32位)
->usage (2位)
–>FRUN 空闲页
–>LRUN 被分配Large内存的第一页
–>SRUN 被分配为了 Small 内存
->lrun_pages (10位)被分配的页数
->srun_bin_num
–>bin number(5位)预定义的small size大小