Python/Jupyter 笔记本内存泄漏

Memory Leak in Python/Jupyter Notebook

通过 运行仅 单个 Jupyter Notebook 单元格中的以下代码,我加载了一个 1GB in memory in a function and I return 函数定义后的结果:

import pickle

def fun():
    with open('./data/input/train_test_clevr_pkls/train_clevr_1000.pkl', 'rb') as handle:
        return pickle.load(handle)

fun()

Jupyter Notebook 随后将打印该函数的输出。查看我 运行 单元格后消耗的内存,它按预期位于 1GB。但是,如果我 运行 同一个单元多次,内存占用每次都会增加 1GB,直到我的整个 RAM 都被消耗完,然后我的 Windows 操作系统使用页面文件交换来处理更多标记为正在使用的内存consumed 这破坏了我的应用程序的性能。我已经尝试使用 gc.collect() 来释放内存但无济于事。

我看到有类似的问题被问到,但我没有找到我的问题的答案。内存没有在内部重用,它只会增长!

您看到这个的原因是因为 Jupyter 存储了对名为 Out.

的名称的所有引用

MRE(所有这些都在一个单元格中)

from itertools import product

def foo():
    return [*product(range(5), repeat=5)]

[foo() for _ in range(5)]

当你在单元格中 运行 this 时,Jupyter 将其保存到字典中 Out

Out

的部分内容
{1: [[(0, 0, 0, 0, 0),
   (0, 0, 0, 0, 1),
   (0, 0, 0, 0, 2),
   (0, 0, 0, 0, 3),
   (0, 0, 0, 0, 4),
   (0, 0, 0, 1, 0),
   (0, 0, 0, 1, 1),
   (0, 0, 0, 1, 2),
   (0, 0, 0, 1, 3),
   (0, 0, 0, 1, 4),
   (0, 0, 0, 2, 0),
   (0, 0, 0, 2, 1),...}

当您再次 运行 代码块时,它会将该值存储到 Out 中的新键 3。每次您 运行 单元格时,都会向 Out 字典添加新的键值对。

现在解释为什么当你这样做时它不会发生的原因 print(...)

from itertools import product

def foo():
    return [*product(range(5), repeat=5)]

print([foo() for _ in range(5)])

在这种情况下,Jupyter 不会将结果保存到 Out 字典中。无论您 运行 单元格多少次,Out dict 始终是 {}.