Python没有在for循环中释放内存
我正在开发一个函数来处理大的输入数据。然而,由于我不能将所有数据一次装入内存(点积为117703x200000矩阵),所以我将其划分为块,并按部分进行计算 输出仅采用前5个元素(排序后),因此必须为117703x5形状,可以保存在内存中。然而,由于某种原因,随着循环的进行,我的内存消耗一直在增加,直到出现内存错误。你知道为什么吗?代码如下:Python没有在for循环中释放内存,python,numpy,memory,memory-leaks,Python,Numpy,Memory,Memory Leaks,我正在开发一个函数来处理大的输入数据。然而,由于我不能将所有数据一次装入内存(点积为117703x200000矩阵),所以我将其划分为块,并按部分进行计算 输出仅采用前5个元素(排序后),因此必须为117703x5形状,可以保存在内存中。然而,由于某种原因,随着循环的进行,我的内存消耗一直在增加,直到出现内存错误。你知道为什么吗?代码如下: def process_predictions_proto(frac=50): # Simulate some inputs query_e
def process_predictions_proto(frac=50):
# Simulate some inputs
query_embeddings = np.random.random((117703, 512))
proto_feat = np.random.random((200000, 512))
gal_cls = np.arange(200000)
N_val = query_embeddings.shape[0]
pred = []
for i in tqdm(range(frac)):
start = i * int(np.ceil(N_val / frac))
stop = (i + 1) * int(np.ceil(N_val / frac))
val_i = query_embeddings[start:stop, :]
# Compute distances
dist_i = np.dot(val_i, proto_feat.transpose())
# Sort
index_i = np.argsort(dist_i, axis=1)[::-1]
dist_i = np.take_along_axis(dist_i, index_i, axis=1)
# Convert distances to class_ids
pred_i = np.take_along_axis(
np.repeat(gal_cls[np.newaxis, :], index_i.shape[0], axis=0),
index_i, axis=1)
# Use pd.unique to remove copies of the same class_id and
# get 5 most similar ids
pred_i = [pd.unique(pi)[:5] for pi in pred_i]
# Append to list
pred.append(pred_i)
# Free memory
gc.collect()
pred = np.stack(pred, 0) # N_val x 5
return pred
在调用
gc.collect()
之前删除所有临时变量,以便数据立即变成垃圾
del start, stop, val_i, dist_i, index_i, dist_i, pred_i
gc.collect()
在代码中,当您第一次调用
gc.collect()
时,所有数据都不是垃圾,因为它仍然可以从所有变量引用。直到第二次迭代结束,才会收集第一次迭代的数据;在第一次迭代之后的每次迭代中,内存中将有两块数据(当前迭代和上一次迭代)。因此,您使用的内存是所需内存的两倍(我假设某些对象之间存在引用,因此在循环过程中重新分配变量时,自动GC不会清理对象)。只需将“GC.collect()”放在循环的开头就足够了吗?不,因为这样就不会收集在上一次迭代中分配的对象。