我在大型运行时脚本中遇到问题。此脚本是一个多线程环境,用于执行爬网任务。
在大型执行中,脚本的内存消耗变得很大,在使用guppy hpy分析内存之后,我发现大部分问题都来自字符串。
我没有存储这么多字符串:只需将htmls的内容存入内存,然后将它们存储在db中。之后,不再使用字符串(包含它的变量被分配给下一个字符串)。
问题出现了,因为我看到每个新字符串(使用sys.getrefcount)至少有2个引用(1个来自我的var,1个来自内部)。似乎将另一个值重新分配给我的var并不会删除内部引用,因此字符串仍然在内存中。
我可以做些什么来确保字符串是垃圾回收?
提前谢谢
编辑:
1-我正在使用Django ORM
2-我从2个来源获得所有字符串:
2.1-直接来自socket(urllib2.urlopen(url).read())
2.2-解析响应,并从每个html和馈送系统中提取新的URI
解决
最后,我得到了钥匙。该脚本是Django环境的一部分,似乎Django的地下正在做一些缓存或类似的东西。我关闭了调试,所有都开始按预期工作(重用的标识符似乎删除了对旧对象的引用,并且这些对象被gc收集)。
对于任何使用某种框架层而不是python的人,请注意配置:似乎某些带有密集进程的调试配置会导致内存泄漏
答案 0 :(得分:2)
你说:
我看到每个新字符串(使用sys.getrefcount)至少有2个引用
但你是否仔细阅读了getrefcount()
的描述? :
sys.getrefcount()
object)返回对象的引用计数。计数返回 通常比你想象的高一个,因为它包含了 (临时)引用作为getrefcount()的参数。
您应该详细解释您的问题。
它拥有的HTML字符串的大小是多少? 他们是如何获得的?你确定要关闭所有文件的处理程序,所有套接字连接,....?
答案 1 :(得分:0)
您需要找出谁对您的字符串保留“内部”引用。 也许您用来写入DB的库(您没有指定如何写入DB)。 我发现objgraph对于这样的任务非常有用:https://pypi.python.org/pypi/objgraph
E.g。
import objgraph
objgraph.show_backrefs([mystring], filename='a.png')