编辑:使用Win10和python3.5
我有一个函数,它使用mmap从文件的某个偏移位置删除字节:
def delete_bytes(fobj, offset, size):
fobj.seek(0, 2)
filesize = fobj.tell()
move_size = filesize - offset - size
fobj.flush()
file_map = mmap.mmap(fobj.fileno(), filesize)
file_map.move(offset, offset + size, move_size)
file_map.close()
fobj.truncate(filesize - size)
fobj.flush()
它的工作速度非常快,但是当我在大量文件上运行它时,内存很快就会填满,我的系统就没有响应了。在
经过一些实验,我发现move()方法是这里的罪魁祸首,尤其是移动的数据量(move_size)。
正在使用的内存量相当于mmap.move()
移动的数据总量。
如果我有100个文件,每移动一个~30MB,内存就会充满~3GB。在
为什么移动的数据没有从内存中释放?在
我尝试过的方法没有效果:
gc.collect()
。在
这似乎应该有效。我确实在mmapmodule.c源代码
#ifdef MS_WINDOWS
中发现了一个可疑位。具体地说,在所有解析参数的设置之后,代码将执行以下操作:它将底层文件对象的偏移量从“文件结束”移动到“文件开始”,然后将其保留在那里。这看起来似乎应该不会破坏任何内容,但在调用
mmap.mmap
来映射文件之前,您可能需要自己寻找文件的开头。在(以下都是错误的,但请留下,因为有评论。)
通常,在使用mmap()
之后,必须使用munmap()
来撤消映射。简单地关闭文件描述符没有效果。Linux documentation显式地调用它:(BSD文档类似。在这里,Windows可能与类Unix系统的行为有所不同,但您所看到的情况表明它们的工作方式相同。)
不幸的是,{cdmmap>和{cdmmap>的模块{cdmmap>和{cdmmap>都不调用^.4>和^ cdmmap>模块。作为解决方法,您可以使用
ctypes
模块。请参见this question以获取一个示例(它调用reboot
,但相同的技术适用于所有C库函数)。或者,对于更好的方法,可以在cython中编写包装器。在相关问题 更多 >
编程相关推荐