【发布时间】:2019-07-10 19:24:28
【问题描述】:
我为将任务添加到我的 Celery 队列而编写的脚本正在泄漏内存(到了内核在 20 分钟后终止进程的程度)。在这个脚本中,我只是重复执行相同的 300 个任务,每 60 秒(在 while True: 内)。
传递给任务的参数makeGroupRequest()是包含字符串的字典,根据hpy和objgraph,字典和字符串也是内存中不可控制的增长。我在循环的连续迭代中包含了下面 hpy 的输出。
我已经为此花费了几天时间,但考虑到循环之间没有重复使用任何内容,我无法理解为什么内存会不受控制地增长。如果我跳过任务的检索,内存似乎不会泄漏(因此实际上是 .get() 调用正在泄漏内存)。如何确定发生了什么以及如何阻止增长?
这是正在执行的代码的概要。我正在使用 rpc:// 后端。
while True:
# preparation is done here to set set up the arguments for the tasks (processedChains)
chains = []
for processedChain in processedChains:
# shorthanding
supportingData = processedChain["supportingDataAndCheckedGroups"]
# init the first element, which includes the supportingData and the first group
argsList = [(supportingData, processedChain["groups"][0])]
# add in the rest of the groups
argsList.extend([(groupInChain,) for groupInChain in processedChain["groups"][1:]])
# actually create the chain
chain = celery.chain(*[makeGroupRequest.signature(params, options={'queue':queue}) for params in argsList])
# add this to the list of chains
chains.append(chain)
groupSignature = celery.group(*chains).apply_async()
# this line appears to cause a large increase in memory each cycle
results = groupSignature.get(timeout = 2 * acceptableLoopTime)
time.sleep(60)
这是hpy 在连续运行时的输出:
循环 2:
Partition of a set of 366560 objects. Total size = 57136824 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 27065 7 17665112 31 17665112 31 dict (no owner)
1 122390 33 11966720 21 29631832 52 unicode
2 89133 24 8291952 15 37923784 66 str
3 45448 12 3802968 7 41726752 73 tuple
4 548 0 1631072 3 43357824 76 dict of module
5 11195 3 1432960 3 44790784 78 types.CodeType
6 9224 3 1343296 2 46134080 81 list
7 11123 3 1334760 2 47468840 83 function
8 1414 0 1274552 2 48743392 85 type
9 1414 0 1240336 2 49983728 87 dict of type
循环 3:
Index Count % Size % Cumulative % Kind (class / dict of class)
0 44754 9 29240496 37 29240496 37 dict (no owner)
1 224883 44 20946280 26 50186776 63 unicode
2 89104 18 8290248 10 58477024 74 str
3 45455 9 3803288 5 62280312 79 tuple
4 14955 3 2149784 3 64430096 81 list
5 548 0 1631072 2 66061168 83 dict of module
6 11195 2 1432960 2 67494128 85 types.CodeType
7 11122 2 1334640 2 68828768 87 function
8 1402 0 1263704 2 70092472 88 type
9 1402 0 1236976 2 71329448 90 dict of type
【问题讨论】:
-
每个任务返回什么?可能是您的任务返回的值太大,生产者无法重新使用。
-
每个任务都在构建一个字典,然后将该字典附加到一个列表并返回该列表(该列表被传递给链中的下一个任务)。我刚刚打印出返回值的大小,它在给定周期内从 ~539 字节增长到 ~12890 字节(即第一个任务完成的返回值为 539 字节,最后一个任务的返回值为 12890 字节)。我不应该沿着链手动传递结果吗?我已经完成了另一个脚本并且没有内存泄漏。如何测试您的猜测是否正确?
标签: python memory-leaks rabbitmq celery rpc