2

我在大型运行时脚本中遇到问题。该脚本是一个多线程环境,用于执行爬取任务。

在大型执行中,脚本的内存消耗变得巨大,在使用 guppy hpy 分析内存后,我发现大部分问题都来自字符串。

我没有存储这么多的字符串:只需将 html 的内容放入内存,然后将它们存储在 db 中。在它之后,不再使用字符串(包含它的变量被分配给下一个字符串)。

出现问题是因为我看到每个新字符串(使用 sys.getrefcount)至少有 2 个引用(1 个来自我的 var,1 个来自内部)。似乎将另一个值重新分配给我的 var 并不会删除内部引用,因此字符串仍保留在内存中。

我能做些什么来确保字符串被垃圾收集?

先感谢您

编辑:

1-我正在使用 Django ORM

2-我从 2 个来源获得所有这些字符串:

2.1- 直接来自套接字 (urllib2.urlopen(url).read())

2.2- 解析响应,并从每个 html 和馈送系统中提取新的 URI

解决了

终于,我拿到了钥匙。该脚本是 Django 环境的一部分,似乎 Django 的地下正在做一些缓存或类似的事情。我关闭了调试,一切都开始按预期工作(重用的标识符似乎删除了对旧对象的引用,并且这些对象被 gc 收集)。

对于在 python 上使用某种框架层的任何人,请注意配置:似乎一些具有密集过程的调试配置会导致内存泄漏

4

2 回答 2

2

你说:
我看到每个新字符串(使用 sys.getrefcount)至少有 2 个引用

但是你有仔细阅读过的描述getrefcount()吗?:

sys.getrefcount()

object) 返回对象的引用计数。返回的计数通常比您预期的高一,因为它包含(临时)引用作为 getrefcount() 的参数。

.

你应该更多地解释你的程序。

它包含的 HTML 字符串的大小是多少?
它们是如何获得的?你确定要关闭所有文件的处理程序,所有的套接字连接,......?

于 2013-03-01T11:37:19.850 回答
0

您需要找出谁保留了对您的字符串的“内部”引用。也许是您用来写入 DB 的库(您没有指定写入 DB 的方式)。我发现 objgraph 对于这样的任务非常有用:https ://pypi.python.org/pypi/objgraph

例如

import objgraph
objgraph.show_backrefs([mystring], filename='a.png')
于 2013-03-01T11:14:57.740 回答