笨鸟编程-零基础入门Pyhton教程

 找回密码
 立即注册

调试内存泄漏

发布者: 笨鸟自学网



跟踪哪些对象?

被跟踪的对象 trackrefs 都来自这些类(及其所有子类):

  • scrapy.Request

  • scrapy.http.Response

  • scrapy.Item

  • scrapy.Selector

  • scrapy.Spider

一个真实的例子

让我们来看一个假设的内存泄漏案例的具体示例。假设我们有一只蜘蛛,上面有一条和这条类似的线:

return Request(f"http://www.somenastyspider.com/product.php?pid={product_id}",
               callback=self.parse, cb_kwargs={'referer': response})

该行正在请求中传递一个响应引用,它有效地将响应生命周期与请求的生命周期联系起来,这肯定会导致内存泄漏。

让我们看看如何通过使用 trackref 工具。

当爬虫运行几分钟后,我们注意到它的内存使用量增长了很多,我们可以进入它的telnet控制台并检查实时引用:

>>> prefs()
Live References

SomenastySpider                     1   oldest: 15s ago
HtmlResponse                     3890   oldest: 265s ago
Selector                            2   oldest: 0s ago
Request                          3878   oldest: 250s ago

事实上,存在如此多的实时响应(而且它们太老了),这是绝对可疑的,因为与请求相比,响应的生存期应该相对较短。响应的数量与请求的数量相似,因此看起来它们是以某种方式捆绑在一起的。我们现在可以检查蜘蛛的代码,以发现产生泄漏的讨厌的行(在请求中传递响应引用)。

有时,有关活动对象的额外信息可能会有所帮助。让我们检查最早的回答:

>>> from scrapy.utils.trackref import get_oldest
>>> r = get_oldest('HtmlResponse')
>>> r.url
'http://www.somenastyspider.com/product.php?pid=123'

如果您希望遍历所有对象,而不是获取最旧的对象,则可以使用 scrapy.utils.trackref.iter_all() 功能:

>>> from scrapy.utils.trackref import iter_all
>>> [r.url for r in iter_all('HtmlResponse')]
['http://www.somenastyspider.com/product.php?pid=123',
 'http://www.somenastyspider.com/product.php?pid=584',
...] 

Archiver|手机版|笨鸟自学网 ( 粤ICP备20019910号 )

GMT+8, 2024-9-8 11:16 , Processed in 0.027868 second(s), 17 queries .

© 2001-2020

返回顶部