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 始终是 {}
.
通过 运行仅 单个 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 始终是 {}
.