gpt4 book ai didi

python - 使用 re 和 mmap 时内存泄漏(ish?)

转载 作者:行者123 更新时间:2023-12-05 07:54:02 26 4
gpt4 key购买 nike

我在 python 3.4(64 位 Windows)中跨大型(30 GB)mmapped 文件运行正则表达式搜索时遇到“问题”。

基本上,我观察到的是 匹配命中时,内存占用量大约上升到匹配之间的字节数。它实际上并没有崩溃,但占用空间大到足以减慢其他进程的速度(因为映射文件的大小)。

我的正则表达式来自一个字节串,它非常具体并且所有量词都是有界的。我的表达式中没有 *+,所以这不是可怕的正则表达式溢出的情况(最坏的情况是匹配长度为 2200 字节,大多数匹配更小).我将匹配的字符串存储在一个列表中,但通常最多只有几千个匹配项,所以占用所有空间的不是匹配项。

我目前假设正则表达式引擎(sre 对吗?)将所有匹配项之间的字符串保存在内存中,这对于小数据集来说很好,但对我来说并非如此。所以我的问题真的是:这个假设是否正确,如果是这样,我可以改变这种行为(最好不要重新编译库!)

代码基本上是这样的:

pattern = re.compile(b"PATTERN.{1,20}", re.DOTALL)
f = open("file.bin", "rb")
mem = mmap.map(f.fileno(), 0, access=mmap.ACCESS_READ)

results = []
for match in pattern.finditer(mem):
results.append(match.group(0))

f.close()

最佳答案

我不确定是否有办法解决这个问题。您正在以磁盘可以提供的速度读取大量数据。除非你有大量的内存。如果您在某个时候不这样做,那么您将用完 RAM 必须释放一些内存。大多数操作系统将使用 LRU(最近最少使用)算法来决定将什么踢出 RAM。由于您正在尽可能快地访问数据,因此内存映射文件使用的大部分内存将具有最近的访问时间。因此这意味着它们是被踢出 RAM 的“糟糕”候选人(至少根据操作系统而言)。

基本上,当可用内存用完时,操作系统对于从 RAM 中踢出什么的选择很糟糕。

但是,您更清楚可以释放哪些内存。因此,您可以分块扫描文件。当您不再需要文件的较早部分时,这将明确让操作系统释放该内存。当然,这会在 block 的边界产生问题。

作为提高程序内存性能的示例:

import re
import mmap
import os

filename = "some_file.txt"
file_size = os.stat(filename).st_size
chunk_size = 2**32
# chunk_size = 50 # smaller chunk_size I used for testing
regex = re.compile(rb"PATTERN\d{1,20}\n")
max_length = len("PATTERN") + 20 + len("\n")

matches = []
f = open(filename, "rb")
for i in range(0, file_size, chunk_size - max_length + 1):
# compute length of data to search over
length = chunk_size if i + chunk_size <= file_size else file_size - i

m = mmap.mmap(f.fileno(), length=length, offset=i, access=mmap.ACCESS_READ)
# f.seek(i) # used for testing
# m = f.read(length)

for match in regex.finditer(m):
if not (match.end() == len(m) and len(match.group()) < max_length and length == chunk_size):
# if match ends at end of string
# and not maximum length of regex
# but not also at the end of the file
# THEN there *may* be a cross chunk-boundary match
# THUS, defer match to next loop iteration
matches.append(match.group())
m.close()
f.close()

关于python - 使用 re 和 mmap 时内存泄漏(ish?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31963124/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com