Python numpy.repeat中的内存分配
我的脚本内存泄漏,我将其缩小到Python numpy.repeat中的内存分配,python,numpy,memory,memory-leaks,Python,Numpy,Memory,Memory Leaks,我的脚本内存泄漏,我将其缩小到np。重复。理论上,如果我有一个np.array数组,它有自己的指针,叫做arr,我做一个arr\u repeated=arr.repeat(10,axis=0),然后对这两个数组执行del,它们占用的内存应该被释放吗 我正在核实: psutil.Process(os.getpid()).memory_info().rss 更具体地说,以下代码中的memory\u在之前和memory\u在之后是否应该有所不同 arr = np.array([[1,2,3,...
np。重复。理论上,如果我有一个np.array
数组,它有自己的指针,叫做arr
,我做一个arr\u repeated=arr.repeat(10,axis=0)
,然后对这两个数组执行del
,它们占用的内存应该被释放吗
我正在核实:
psutil.Process(os.getpid()).memory_info().rss
更具体地说,以下代码中的memory\u在
之前和memory\u在
之后是否应该有所不同
arr = np.array([[1,2,3,...], [...], [...]])
arr_repeated = arr.repeat(10, axis = 0)
memory_before = psutil.Process(os.getpid()).memory_info().rss
del arr
del arr_repeated
memory_after = psutil.Process(os.getpid()).memory_info().rss
我有
extra/python numpy 1.13.1-2[已安装]
在我的antergos/arch上,仅仅因为使用了del
变量并不意味着内存立即被释放。它只是删除变量的名称。Pythons引用计数机制和gc
负责释放内存
因此,为了安全起见,您需要使用来强制gc
清除所有可能包含循环引用的内容,否则Python将“在任何时候”清除这些内容(可能只有在内存不足或某一时间之后)
例如,包含以下注释:
注
del x
不直接调用x.\uu del\uu()
-前者将x
的引用计数递减1,后者仅在x
的引用计数达到零时调用。可能会阻止对象的引用计数变为零的一些常见情况包括:对象之间的循环引用(例如,具有父指针和子指针的双链接列表或树数据结构);对捕获异常的函数堆栈帧上的对象的引用(存储在sys.exc_info()[2]
中的回溯使堆栈帧保持活动状态);或者对堆栈帧上在交互模式下引发未处理异常的对象的引用(存储在sys.last\u traceback
中的回溯使堆栈帧保持活动状态)。第一种情况只能通过明确打破循环来补救;第二个问题可以通过在回溯对象不再有用时释放对该对象的引用来解决,第三个问题可以通过在sys.last\u traceback
中存储None
来解决。循环垃圾回收器启用时(默认情况下处于启用状态),将检测并清除作为垃圾的循环引用。有关此主题的更多信息,请参阅本模块的文档
请注意,gc
也有一个检测泄漏的设置:gc.set\u debug(gc.debug\u LEAK)
不确定它是如何工作的,但是值得一试,而不是仅仅因为使用del
变量就使用psutil。它只是删除变量的名称。Pythons引用计数机制和gc
负责释放内存
因此,为了安全起见,您需要使用来强制gc
清除所有可能包含循环引用的内容,否则Python将“在任何时候”清除这些内容(可能只有在内存不足或某一时间之后)
例如,包含以下注释:
注
del x
不直接调用x.\uu del\uu()
-前者将x
的引用计数递减1,后者仅在x
的引用计数达到零时调用。可能会阻止对象的引用计数变为零的一些常见情况包括:对象之间的循环引用(例如,具有父指针和子指针的双链接列表或树数据结构);对捕获异常的函数堆栈帧上的对象的引用(存储在sys.exc_info()[2]
中的回溯使堆栈帧保持活动状态);或者对堆栈帧上在交互模式下引发未处理异常的对象的引用(存储在sys.last\u traceback
中的回溯使堆栈帧保持活动状态)。第一种情况只能通过明确打破循环来补救;第二个问题可以通过在回溯对象不再有用时释放对该对象的引用来解决,第三个问题可以通过在sys.last\u traceback
中存储None
来解决。循环垃圾回收器启用时(默认情况下处于启用状态),将检测并清除作为垃圾的循环引用。有关此主题的更多信息,请参阅本模块的文档
请注意,gc
还有一个检测泄漏的设置:gc.set\u debug(gc.debug\u LEAK)
不确定它到底是如何工作的,但它可能值得一试,而不是使用psutil
是的,忘记了gc,我现在看到它可以在示例代码上工作。不幸的是,在我的主脚本中不起作用,但我想还有更多的链接somewhere@gavlig它仍然可能是引用或内存泄漏,我只是说依靠del
清理内存是错误的假设。如果您真的怀疑内存泄漏,您应该使用valgrind之类的工具,或者向NumPy开发人员报告。:)@gavlig请注意,视图会使原始阵列保持活动状态,因此,如果您拥有1000x1000阵列的2x2视图并保持该视图,则会使1000x1000阵列保持活动状态!这件事在我身上发生过好几次。在这些情况下,您可以简单地复制视图以删除指向原始视图的链接。但这只是猜测而不知道您的代码-您可能需要自己检查一下。是的,忘记了gc,我知道它现在可以在示例代码上工作。不幸的是,在我的主脚本中不起作用,但我想还有更多的链接somewhere@gavlig它仍然可能是引用或内存泄漏,我只是说依靠del
清理内存是错误的假设。如果你真的怀疑内存泄漏,你应该使用一些工具,比如valgrind或者向NumPy开发者报告
import numpy as np
import psutil
import os
import gc
arr = np.array([list(range(10000)), list(range(10000)), list(range(10000))])
arr_repeated = arr.repeat(10, axis = 0)
gc.collect()
memory_before = psutil.Process(os.getpid()).memory_info().rss
del arr
del arr_repeated
gc.collect()
memory_after = psutil.Process(os.getpid()).memory_info().rss