【问题标题】:Python: how to garbage collect stringsPython:如何垃圾收集字符串
【发布时间】:2013-02-15 20:49:14
【问题描述】:

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

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

我没有存储这么多的字符串:只需将 html 的内容放入内存,然后将它们存储在 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 上使用某种框架层的人,请注意配置:似乎一些具有密集过程的调试配置可能会导致内存泄漏

【问题讨论】:

  • 你试过 del(my_str_var) 吗?
  • 如果sys.getrefcount返回2,则没有内部引用,因为当你将对象传递给sys.getrefcount时。它会增加引用计数。
  • 我只是将新字符串分配给旧变量。显然我信任pythons的垃圾收集器,但似乎还不够。将尝试在每个字符串调用中添加一个“del”
  • just get content of htmls into memory 实际 问题在哪里。
  • 只需将 html 的内容放入内存 不是我的问题。我从 obj1.var1 = urllib2.urlopen(url).read() 得到 1 个 HTML,然后处理 obj1,然后是 del(obj1);在这一步之后,我处理下一个,重新分配给一个新对象 obj2

标签: python string garbage-collection


【解决方案1】:

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

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

sys.getrefcount()

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

.

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

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

【讨论】:

  • HTML 的大小是任意的(有些很短,有些很大)。我获取它,存储在对象变量中,处理整个对象,然后删除对象。没有一个例外出现让带有引用的对象(我跟踪过),但是当我重用所有变量时,系统中仍然有越来越多的字符串(用 guppy heapy 跟踪)
  • @user989501 我的意思是 Python 中没有可用的对象应该被称为“变量”。 (有一些底层指针是真正的变量,但它们是不可访问的)
  • 我认为任何具有编程背景(任何语言)的人都可以理解“变量”的含义,并且可以理解对python环境的翻译(一些标识符引用内存中的某些内容)。我不认为我的话会误导别人认为 python 的标识符是另一回事
  • 我不喜欢不正确的措辞:它会在概念上蒙上一层模糊的面纱,而且编程很困难,不会在头脑中添加模糊的文字。
【解决方案2】:

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

例如

import objgraph
objgraph.show_backrefs([mystring], filename='a.png')

【讨论】:

  • 我正在使用 objgraph,但无法获取有关字符串的信息(它不会跟踪有关将“简单”称为整数或字符串的对象的信息)
猜你喜欢
  • 1970-01-01
  • 2013-02-25
  • 2013-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 2011-01-21
  • 1970-01-01
相关资源
最近更新 更多