添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Python (+django) 在简单的脚本中没有垃圾收集功能

0 人关注

我有一个python的脚本。 它使用django的模型从数据库中获取一些(准确地说:很多)数据。

快速 "总结 "一下我想实现的目标(可能不是很重要,所以你也可以通过看代码来了解)。
有A类型的对象。
对于每个A对象,都有B类型的相关对象(1到多)。
对于每个B类对象,都有相关的C类对象(1到多)。
对于每个C对象,都有一个相关的对象,对我来说特别有趣--我们称之为D(1对1关系)。

对于数据库中的每个A对象(不多),我需要得到与之相关的所有B对象和与之相关的所有D对象来创建A对象的摘要。每个摘要都是一个单独的工作表(我使用的是 openpyxl ).

我写的代码是有效的(意思是:它做了我想做的事),但在垃圾收集方面有问题,所以进程被杀死。我试过不使用预取,因为时间不是那么重要,但这并没有什么帮助。

摘要代码。

a_objects = A.objects.all()
wb = Workbook()
for a_object in a_objects:
    ws = wb.create_sheet()
    ws.title = a.name
    summary_dictionary = {}
    b_objects = B.objects.filter(a_object=a_object)
    for b_object in b_objects:
        c_objects = C.objects.filter(b_object=b_object)
        for c_object in c_objects:
            # Here i put a value in dictionary, or alter it, 
            # depending on whether c_object.d_object has unique fields for current a_object
            # Key is a tuple of 3 floats (taken from d_object)
            # Value is array of 3 small integers (between 0 and 100) 
    summary_dictionary = sorted(summary_dictionary.items(), key=operator.itemgetter(0))
    for summary_item in summary_dictionary:
        ws.append([summary_item[0][0], summary_item[0][1], summary_item[0][2], summary_item[1][0], summary_item[1][1], summary_item[1][2], sum(summary_item[1])])
wb.save("someFile.xlsx")

虽然理论上整个xlsx文件可能很大--可能超过1GB,但如果所有的d_objects值都是唯一的,我估计即使在脚本结束时,它也会低于100MB。在脚本执行过程中,系统中大约有650MB的可用内存。

大约有80个A对象,脚本在其中6、7个对象后被杀死。我用 "top "来监控内存的使用情况,没有发现任何内存被释放,这很奇怪,因为,比方说。
第三个a_object有1000个b_object与之相关,每个b_object有30个c_object与之相关,并且
第4个a_object只有100个b_objects与之相关,每个b_object只有2个c_objects与之相关。

A lot of memory should be freed some time after <<1>> in 4th iteration, right? 我的观点是,我认为这个程序的表现应该是,只要以下内容能装进内存,它就会运行。
- 全文摘要
- 对于数据库中的任何a_object来说,是一个包含所有b_objects及其c_objects和d_objects的单一集合。

那么我错过了什么呢?

python
django
model
garbage-collection
piezol
piezol
发布于 2015-08-28
2 个回答
Brendan W
Brendan W
发布于 2022-07-07
0 人赞同

Try switching:

a_objects = A.objects.all()