首先说明,这些还仅限于我的理解阶段,可能有很多错误或者问题,欢迎各位指正以便于补足我的理解。
大家都或多或少的知道,memcached里面有一套特殊的内存管理机制。长话短说,即内存池。当某个数据要被存储时,首先系统根据该数据大小去找已分配而未使用的内存,如果有,则把数据存储在这块内存区域。
例如 188
数据(200) ----- 210
220
其中三块188,210,220大小的内存区域都是已经分配的区域,但是没有被使用。当数据200大小要存储时,则选择最切近的210大小去存储数据,即便有10大小空闲,也无妨。
如果没有空闲内存区域,则会根据数据大小malloc一个内存,用来存储数据。
当内存使用后,不用释放内存,该内存会被放入一个空闲的队列供后来者使用。
python中也有类似机制。不过python采用的block-pool-arean是预先分配内存大小的。大家可以在源码中看到。
其中,block的分配上限是256。
内存的区间 大小 索引
* 1-8 8 0
* 9-16 16 1
* 17-24 24 2
* 25-32 32 3
* 33-40 40 4
* 41-48 48 5
* 49-56 56 6
* 57-64 64 7
* 65-72 72 8
* ... ... ...
* 241-248 248 30
* 249-256 256 31
然后当数据分配时在预分配的内存中寻找适合大小的区域。原则与memcached有点类似。
memcached这么做,主要是根据数据大小来避免频繁申请内存导致的内存碎片。而python这里也类似。但我颇不理解的是,在PyObject_malloc分配时,大小与Py_ssize_t有直接关系。
如果超过这个大小,意味着只能用Pymem_malloc分配,你可以认为其于c的malloc类似。
由于很多py程序中无法直接去操作内存,无法直接去控制内存的malloc与free,因此可能连最后一次改正的机会都没有了。
这样便导致,如果您的项目需要频繁的操作内存,而且内存超过这些限制,可能便导致一些内存碎片的问题。