我正在运行以下代码:
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空闲23960缓存]),Windows任务管理器列表中Python占用的内存为3GB。我正在观察这个数字,在三天内对文件集合运行代码时增长。
我原以为,由于我正在进行所有操作
tagged = header.process_tagged('G:')
每个循环关联的内存都将被释放和垃圾回收。有什么方法可以强制释放这些内存吗?尽管我还没有运行统计数据,但通过观察磁盘上的活动,我可以看出随着时间的推移(以及内存块变得越来越大),该进程会变慢。
编辑:我查看了下面引用的问题,我认为它们与我的问题不同。在另一个问题中,他们抓住了对象(三角形列表)并需要整个列表进行计算。每次循环时,我都会读取文件,对文件进行一些处理,然后将其写回磁盘。然后我再读取下一个文件...
关于可能的内存泄漏,我正在使用myObject中的LXML。
请注意,自从第一次提问以来,我添加了从MyUtilities导入myObject的代码。MyUtilities包含完成所有操作的代码。
关于发布我的myUtilities代码 - 那会远离基本问题 - 在每次迭代后,我都会完成标题和标记,标记会执行操作并将结果写入另一个驱动器,实际上是新格式化的驱动器。
更新-所以,在myObject类中有一种情况,其中一个文件是用以下方式打开的:
myString = open(somefile).read()
我将其更改为
with open(somefile,'r') as fHandle:
` myString = fHandle.read()`
抱歉,格式有些混乱——我还在努力学习中。
但是这似乎没有明显的影响。当我开始一个新的循环时,我的Cached内存有4000 mb,经过22分钟和处理27K个文件后,我大约有26000 mb的Cached内存。
我感谢下面所有的答案和评论,并一整天阅读并测试各种内容。如果这项任务本来需要一周时间,现在看起来可能需要一个月以上。
我一直得到有关代码其余部分的问题。然而,它超过800行,对我来说那样就不太与中心问题相关了。
所以先创建一个myObject实例,然后将myObject中包含的方法应用于header。
这基本上是文件转换。一个文件被读入,然后复制文件的某些部分并写入磁盘。
对我来说,中心问题是header或tagged显然具有某种持久性。在开始下一个周期之前,如何处理与header或tagged相关的所有内容。
我现在已经运行了代码14个小时左右。第一个周期的处理大约需要22分钟,处理27K个文件,现在处理大约相同数量需要一个半小时左右。
仅运行gc.collect是不起作用的。我停止了程序并在解释器中尝试了一下,但没有看到内存统计数据有任何变化。
编辑后阅读了下面的memoryallocator说明,我认为与缓存相关的数量不是问题——而是运行python进程所占用的数量。所以新的测试是从命令行运行代码。我将继续观察和监控,并在看到结果后发布更多内容。
编辑:仍在努力中,但已经设置了代码从一个bat文件开始运行,并带有sgmlFilings
的一个循环中的数据(见上文)。批处理文件如下:
python batch.py
python batch.py
.
.
.
batch.py首先读取一个队列文件,该文件包含要glob的目录列表,它将第一个目录从列表中取出,更新列表并保存,然后运行header
和tagged
进程。虽然有点笨拙,但是由于每次迭代后python.exe都会关闭,因此python不会累积内存,因此该过程以一致的速度运行。