为啥垃圾回收这么慢?

Posted

技术标签:

【中文标题】为啥垃圾回收这么慢?【英文标题】:Why is Garbage Collection so Slow?为什么垃圾回收这么慢? 【发布时间】:2015-12-20 06:04:01 【问题描述】:

使用 %prun 在 IPython 中分析我的代码,我注意到大部分函数时间都用于垃圾收集(0.334 秒对 0.428 总时间)。

79254 function calls (77408 primitive calls) in 0.428 seconds

Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     5    0.334    0.067    0.334    0.067 gc.collect
 15757    0.005    0.000    0.007    0.000 isinstance
  1584    0.002    0.000    0.004    0.000 dtypes.py:68(is_dtype)

我尝试在调用函数之前和返回其值之后禁用/启用垃圾收集,但时间几乎相同。

import gc

gc.disable()
x = foo()
gc.disable()

有谁知道为什么这是一个瓶颈以及如何加快速度?

我的 Python/Pandas 版本如下:

Python 2.7.11 |Continuum Analytics, Inc.| (default, Dec  6 2015, 18:57:58) 
Pandas 0.17.1

【问题讨论】:

我猜你的代码会产生很多垃圾。 我猜答案是“不”,但你能在这里分享任何代码吗?否则,也许你可以写一些东西来证明这个 gc 问题。 :s @AndyHayden 我还在分析。看起来瓶颈是一个运行大量回归的函数。如果我能整理出 MVE,我会编辑我的帖子。 另一个想法是覆盖gc.collect = lambda: None(然后放回去!)。也许更深层次的东西是启用 gc 和手动收集。不知道这是否真的有效,但值得一试。 @stefan 不,它已从我的优先事项中删除。实际上我可能很快会再次访问它,所以如果有任何更新,我会提供更新。 【参考方案1】:

垃圾收集是许多现代语言的高级功能/抽象。它使程序变慢,但也使程序更不容易出错并且更容易创建。

这里有一些关于这个特定主题的好文章:

Python GarbageOnly slow if you use it wrong

【讨论】:

嘿,在 GC 部分只有慢说TODO: find out what he meant somehow【参考方案2】:

您禁用了gc,因此实际上可能有一些东西明确地调用了gc.collect。你可以通过在 IPython 中使用这个技巧找到罪魁祸首:

import gc
import traceback

old_collect = gc.collect

def new_collect(*args, **kwargs):
    traceback.print_stack()
    old_collect(*args, **kwargs)

gc.collect = new_collect

请注意,它仅在代码执行 import gc 时才有效,它不适用于 from gc import collect(我们正在操作 gc 模块)。

如果发现问题,请报告错误。

【讨论】:

以上是关于为啥垃圾回收这么慢?的主要内容,如果未能解决你的问题,请参考以下文章

为啥调用 DetachCurrentThread() 会导致过多的垃圾回收?

搞定 JVM 垃圾回收就是这么简单

为啥指定的对象有资格进行垃圾回收?

未使用的 JPA 实体是不是被垃圾回收?为啥?

js基础_垃圾回收

04_垃圾回收器