gpt4 book ai didi

python - 强制Python释放对象以释放内存

转载 作者:行者123 更新时间:2023-11-28 19:48:44 28 4
gpt4 key购买 nike

我运行以下代码:

from myUtilities import myObject
for year in range(2006,2015):
front = 'D:\\newFilings\\'
back = '\\*\\dirTYPE\\*.sgml'
path = front + str(year) + back
sgmlFilings = glob.glob(path)
for each in sgmlFilings:
header = myObject(each)
try:
tagged = header.process_tagged('G:')
except Exception as e:
outref = open('D:\\ProblemFiles.txt','a')
outref.write(each '\n')
outref.close()
print each

如果从重新启动开始,python的内存分配/消耗相当小。随着时间的推移,虽然它会显著增加,但最终大约一天之后,我的可用内存非常少(已安装24GB[294 mb free 23960 cached]),Python在Windows任务管理器列表中声明的内存是3GB。我正看着这三天的增长,它需要对文件集合运行代码。
我的印象是,既然我和
tagged = header.process_tagged('G:')

与每个循环相关联的内存将被释放并垃圾回收。
我能做些什么来释放这种记忆吗。虽然我还没有运行统计数据,但通过观察磁盘上的活动可以看出,随着时间的推移(内存块变大),进程会变慢
编辑
我看了下面提到的问题,我认为这些问题与我在另一个问题中理解的问题不一样,那就是它们抓住了对象(三角形列表),需要整个列表进行计算。在每个循环中,我读取一个文件,对该文件执行一些处理,然后将其写回磁盘。然后我在读下一个文件。. .
关于可能的内存泄漏,我在myObject中使用LXML
注意,自从这个问题的第一次迭代以来,我添加了MyUtilities import myObject中的行。MyUtilities保存执行所有操作的代码
关于发布我的myUtilities代码-这远离了基本问题-我已经完成了头和标记,在每次迭代后标记完成了工作,并将结果写入另一个驱动器,实际上是一个新格式化的驱动器。
我研究了使用多处理,但我没有,因为一个模糊的想法,因为这是如此的I/O密集,我会竞争驱动器头-也许这是错误的,但由于每次迭代需要我写几百MB的文件,我想我会竞争写,甚至读时间。
更新-所以我在myObjectclass中有一个案例,其中一个文件是用
myString = open(somefile).read()
我改成了
with open(somefile,'r') as fHandle:
`    myString = fHandle.read()`

(抱歉格式化-仍在挣扎)
然而,这并没有明显的影响,当我开始一个新的循环时,我有4000MB的缓存,经过22分钟和27K文件的处理,我有大约26000MB的缓存。
我很欣赏下面所有的答案和评论,并且整天都在阅读和测试各种各样的东西。我会更新这个,因为我认为这项任务需要一个星期,现在看来可能需要一个多月。
我一直在问其他代码的问题。但是,它有800多条线路,对我来说,这样就远离了中心问题
所以创建了一个myObject实例
然后我们将myObject中包含的方法应用于header
这基本上就是文件转换。文件被读入,部分文件的拷贝被制作并写入磁盘。
我的核心问题是,显然有一些持久性,无论是头部还是标记。如何在开始下一个循环之前处理与标题或标记相关的所有内容。
我已经运行代码14个小时左右了。当它经过第一个周期时,大约需要22分钟来处理27 K文件,现在需要大约一个半小时来处理大约相同的数字。
只是运行gc.collect不起作用。我停止了程序,并在解释器中尝试了这一点,我看到内存统计数据没有任何变化。
从下面阅读memoryallocator描述后编辑我认为缓存中的绑定量不是问题-它是由运行的python进程绑定的量。所以新的测试是从命令行运行代码。我将继续观察和监测,并将张贴更多的,一旦我看到发生了什么。
编辑:仍在挣扎,但已将代码设置为从bat文件运行,其中包含 sgmlFilings(请参见上文)的一个循环中的数据批处理文件如下所示
python batch.py
python batch.py
.
.
.

py首先读取一个队列文件,该文件有一个要全局搜索的目录列表,从列表中取出第一个,更新列表并保存它,然后运行 headertagged进程。很笨拙,但由于python.exe在每次迭代后都会关闭,因此python不会累积内存,因此进程以一致的速度运行。

最佳答案

原因是CPython的内存管理。Python管理内存的方式使得长时间运行的程序变得困难。当使用del语句显式释放对象时,CPython不一定会将分配的内存返回给OS。它保留了内存以备将来使用。解决此问题的一种方法是使用多处理模块,并在完成作业并创建另一个作业后终止该进程。这样您就可以通过强制释放内存,操作系统必须释放该子进程使用的内存。
我也有同样的问题。随着时间的推移,内存使用过度增加,以至于系统变得不稳定和无响应。我对信号和psutil使用了不同的技术来解决这个问题。例如,当您有一个循环并且需要在堆栈上分配和释放数据时,通常会出现此问题。
您可以在这里阅读有关Python内存分配器的更多信息:http://www.evanjones.ca/memoryallocator/
此工具也非常有助于分析内存使用情况:https://pypi.python.org/pypi/memory_profiler
还有一件事,向myObject添加插槽,看起来对象中有固定的插槽,这也有助于减少ram的使用。没有指定插槽的对象会分配更多的ram来处理稍后可能添加到它们的动态属性:http://tech.oyster.com/save-ram-with-python-slots/

关于python - 强制Python释放对象以释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31089451/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com