分块分配程序#

以前的设计#

历史上 Pillow 中有两个图像分配器: ImagingAllocateBlockImagingAllocateArray . 第一种方法适用于小于16MB数据的图像,并分配一大块 im->linesize * im->ysize 字节。第二个用于大图像,并为每个扫描行的大小进行一次分配 im->linesize 字节。这使得在一个分配和可能的数千个小分配之间实现了一个非常急剧的过渡,从而导致在过渡期间出现不可预测的性能损失。

新设计#

ImagingAllocateArray 现在将图像的空间分配为最大大小为16MB的块链。如果存在内存分配错误,则返回到分配4KB块或至少一条扫描线。这现在是所有内部分配的默认值。

ImagingAllocateBlock 现在只在我们特别请求单个内存段与其他代码共享时用于这些情况。

内存池#

现在有一个内存池来包含最近释放的块的供应,然后可以重用这些块,而不必返回操作系统进行新的分配。默认情况下,当前禁用自由块的缓存,但可以使用三个环境变量启用和调整:

  • PILLOW_ALIGNMENT ,以字节为单位。指定内存分配的对齐方式。有效值是介于1和128之间(含1和128)的2的幂。默认值为1。

  • PILLOW_BLOCK_SIZE ,以字节、k或m为单位。指定 ImagingAllocateArray . 有效值为整数,可选 km 后缀。默认为16米。

  • PILLOW_BLOCKS_MAX 指定为满足将来的内存请求而保留的释放块数。超过此阈值的任何释放块都将立即返回到操作系统。默认值为0。