面试题答案
一键面试1. 预分配策略
- 场景:在Redis的二进制位数组(如
SDS
,简单动态字符串,它类似二进制位数组结构)中,当预计到可能需要增长时,提前分配一定量的额外空间。例如,当要向一个SDS
中追加字符串时,如果已知追加的内容长度,Redis不是只分配追加内容所需的空间,而是额外多分配一些空间。 - 内存管理优势:这样做可以减少频繁的内存分配操作。因为每次分配内存都可能涉及系统调用等开销,预分配能将多次小的内存分配合并为一次大的分配,从而减少内存碎片产生。例如,假设要不断向
SDS
中追加少量数据,如果每次追加都只分配刚好够用的内存,随着追加次数增多,内存中会产生许多小块的空闲空间,即内存碎片;而预分配策略可以避免这种情况。
2. 内存分配算法选择
- 场景:Redis通常使用jemalloc作为内存分配器。jemalloc针对多线程环境进行了优化,它采用了一种分层的内存分配策略。
- 内存管理优势:在二进制位数组扩展时,jemalloc能够更有效地管理内存,减少内存碎片。它会根据请求的内存大小,从不同的内存池(如小对象内存池、大对象内存池等)中分配内存。例如,对于二进制位数组扩展时较小的内存需求,jemalloc会从适合小对象分配的内存池中获取内存,这些内存池采用了特定的数据结构(如bin等)来管理空闲块,能快速找到合适的空闲块进行分配,减少内存碎片的产生。相比简单的malloc,jemalloc在多线程、频繁分配释放场景下表现更好,这对于Redis这种高并发的应用非常关键。
3. 按需释放策略
- 场景:当二进制位数组中的数据减少,导致占用空间大幅下降时,Redis并不会立即将多余的空间归还给操作系统,而是保留在自身的内存管理体系中供后续使用。但当确定不再需要这些空间时,会进行释放。
- 内存管理优势:这种策略避免了频繁地向操作系统申请和归还内存。例如,如果二进制位数组频繁地扩展和收缩,如果每次收缩都将空间归还给操作系统,下次扩展又要从操作系统申请,这会导致操作系统内存管理的碎片化,同时也增加了系统调用开销。通过按需释放,在进程内合理管理这些内存,可有效减少内存碎片,提高内存使用效率。