现在,可能是5万里的某个东西非常大,这导致了OOM,所以为了测试这个,我首先尝试:file_list_chunks = list(divide_chunks(file_list_1,20000))[30000:]
如果它在10000失败,这将确认20k是否太大的chunksize,或者如果它再次在50000失败,代码有问题。。。在
好吧,注意密码。。。在
首先,您不需要显式的list构造函数,在python中,迭代比将整个列表生成内存要好得多。在
^{pr2}$
我想你可能在这里误用了线程池:Prevents any more tasks from being submitted to the pool. Once all the tasks have been completed the worker processes will exit.
这看起来像close可能有一些想法仍在运行,但我想这是安全的,感觉有点不正常,最好使用线程池的上下文管理器:with ThreadPool(64) as pool:
results = pool.map(get_image_features,f)
# etc.
python中显式的dels。在
您应该在join/with之后收集with ThreadPool(..):
...
pool.join()
gc.collect()
你也可以试着把它分成小块,比如10000块甚至更小!在
液压锤1
有一件事,我会考虑在这里做,而不是使用pandas数据帧和大列表,而是使用SQL数据库,您可以在本地使用sqlite3:import sqlite3
conn = sqlite3.connect(':memory:', check_same_thread=False) # or, use a file e.g. 'image-features.db'
并使用上下文管理器:with conn:
conn.execute('''CREATE TABLE images
(filename text, features text)''')
with conn:
# Insert a row of data
conn.execute("INSERT INTO images VALUES ('my-image.png','feature1,feature2')")
这样,我们就不必处理大型列表对象或数据帧。在
你可以把连接传递到每个线程。。。你可能会有点奇怪,比如:results = pool.map(get_image_features, zip(itertools.repeat(conn), f))
然后,在计算完成后,您可以从数据库中选择所有内容,并将其转换为您喜欢的任何格式。E、 g.使用read_sql。在
液压锤2
在这里使用一个子进程,而不是在同一个python实例中“shell out”运行到另一个实例中。在
因为可以将start和end作为系统参数,您可以将这些切片:# main.py
# a for loop to iterate over this
subprocess.check_call(["python", "chunk.py", "0", "20000"])
# chunk.py a b
for count,f in enumerate(file_list_chunks):
if count < int(sys.argv[1]) or count > int(sys.argv[2]):
pass
# do stuff
这样,子进程将正确地清理python(不可能存在内存泄漏,因为进程将被终止)。在
我敢打赌Hammer 1是最好的选择,它让人感觉像是把大量的数据粘在一起,不必要地把它读入python列表中,而使用sqlite3(或其他一些数据库)完全避免了这一点。在