【问题标题】:Does my code leak memory (python)?我的代码是否泄漏内存(python)?
【发布时间】:2009-11-28 03:03:52
【问题描述】:
    links_list = char.getLinks(words)
    for source_url in links_list:
        try:
            print 'Downloading URL: ' + source_url
            urldict = hash_url(source_url)
            source_url_short = urldict['url_short']
            source_url_hash = urldict['url_short_hash']
            if Url.objects.filter(source_url_short = source_url_short).count() == 0:
                    try:
                        htmlSource = getSource(source_url)
                    except:
                        htmlSource = '-'
                        print '\thtmlSource got an error...'
                new_u = Url(source_url = source_url, source_url_short = source_url_short, source_url_hash = source_url_hash, html = htmlSource)
                new_u.save()
                time.sleep(3)
            else:
                print '\tAlready in database'
        except:
            print '\tError with downloading URL..'
            time.sleep(3)
            pass


def getSource(theurl, unicode = 1, moved = 0):
    if moved == 1:
        theurl = urllib2.urlopen(theurl).geturl()
    urlReq = urllib2.Request(theurl)
    urlReq.add_header('User-Agent',random.choice(agents))
    urlResponse = urllib2.urlopen(urlReq)
    htmlSource = urlResponse.read()
    htmlSource =  htmlSource.decode('utf-8').encode('utf-8')
    return htmlSource

基本上这段代码的作用是......它需要一个 URL 列表并下载它们,将它们保存到数据库中。就是这样。

【问题讨论】:

  • 您认为您的代码泄漏内存的原因是什么?
  • 发生任何错误?或花费太多时间?不过这有点奇怪,htmlSource.decode('utf-8').encode('utf-8'),它从 utf8 解码并同时编码回 utf8。
  • 没有错误发生。但是,我的脚本随机被“杀死”。而且之前有人说是内存泄露,导致我的内存超负荷了。
  • 如果你在一些共享的虚拟主机上,爬网站不是很好的主意,因为有时,它需要很长时间,甚至有时根本没有响应,在这种情况下,你的脚本会留在内存中,并且一些主机可能会放置自动杀死脚本来保护其他客户。
  • 内存泄漏是指您分配内存并以一种或另一种方式丢失地址并且不会释放分配。你什么都没做。您的脚本被随机杀死,大多数未处理可能是由于异常。改进脚本的调试并尝试重现问题,看看它为什么会被杀死。

标签: python memory memory-management


【解决方案1】:

也许您的进程使用了​​太多内存,而服务器(可能是共享主机)只是因为您耗尽了内存配额而将其杀死。

这里你使用了一个可能会占用大量内存的调用:

links_list = char.getLinks(words)
for source_url in links_list:
     ...

看起来您可能正在内存中构建一个完整的列表,然后处理项目。相反,使用迭代器可能会更好,其中一次检索一个对象。但这是一个猜测,因为很难从您的代码中看出 char.getLinks 的作用

如果您在调试模式下使用 Django,那么内存使用量将会增加,正如 Mark 所建议的那样。

【讨论】:

    【解决方案2】:

    如果您在 Django 中执行此操作,请确保 DEBUG 为 False,否则它将缓存每个查询。

    See FAQ

    【讨论】:

      【解决方案3】:

      最简单的检查方法是转到任务管理器(在 Windows 上 - 或其他平台上的等效设备)并检查 Python 进程的内存要求。如果它保持不变,则没有内存泄漏。如果没有,你在某处有内存泄漏,你需要调试

      【讨论】:

        【解决方案4】:

        也许您应该获得一个工作服务器,例如 beanstalkd,并考虑一次只做一个。

        作业服务器将重新排队失败的那些,让其余的完成。如果需要,您还可以同时运行多个客户端(即使在多台机器上)。

        更简单的设计、更容易理解和测试、更容错、可重试、更可扩展等...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-04
          • 1970-01-01
          • 1970-01-01
          • 2017-12-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多