块分配器

先前设计

历史上,Pillow 中有两个图像分配器:ImagingAllocateBlockImagingAllocateArray。第一个适用于数据小于 16MB 的图像,并分配一个大小为 im->linesize * im->ysize 字节的大块内存。第二个适用于大型图像,并为每个大小为 im->linesize 字节的扫描线进行一次分配。这导致了在一个分配和可能数千个小分配之间发生了非常急剧的转变,从而导致在转变周围出现了不可预测的性能损失。

新设计

ImagingAllocateArray 现在将图像空间分配为一串块,最大大小为 16MB。如果出现内存分配错误,它将回退到分配一个 4KB 块,或者至少分配一行。现在,这成为所有内部分配的默认设置。

ImagingAllocateBlock 现在仅用于我们专门请求内存的单个段以与其他代码共享的情况。

内存池

现在有一个内存池来包含一批最近释放的块,这些块可以在不返回到操作系统进行新分配的情况下重复使用。这种空闲块的缓存目前默认情况下是禁用的,但可以使用三个环境变量启用和调整

  • PILLOW_ALIGNMENT,以字节为单位。指定内存分配的对齐方式。有效值为 1 到 128 之间的 2 的幂,包括 1 和 128。默认为 1。

  • PILLOW_BLOCK_SIZE,以字节、K 或 M 为单位。指定 ImagingAllocateArray 的最大块大小。有效值为整数,可选的后缀为 km。默认为 16M。

  • PILLOW_BLOCKS_MAX 指定要保留的已释放块的数量,以填充未来的内存请求。超过此阈值的任何已释放块将立即返回到操作系统。默认为 0。