【问题标题】:Memory usage while parsing XML file into Google App Engine datastore将 XML 文件解析到 Google App Engine 数据存储区时的内存使用情况
【发布时间】:2013-07-30 06:25:37
【问题描述】:

我正在尝试将一个大 (5GB) XML 文件(产品目录)解析到一个谷歌数据存储中。我遇到的问题是它占用了大量内存。通过逐行读取并删除元素,我能够从解析部分中获取内存。但是有些东西仍然存在。

我的代码是http://pastebin.com/ESARQikC

我认为问题出在此特定功能中

def process_element(self,item):
    if item.tag == "programname":
        self.Plist.append(item.text)
    elif item.tag == 'name':
        self.Plist.append(item.text)        
    elif item.tag == 'description':
        self.Plist.append(item.text)
    elif item.tag == 'sku':
        self.Plist.append(item.text)
    elif item.tag == 'manufacturer':
        self.Plist.append(item.text)
    elif item.tag == 'price':
        self.Plist.append(item.text)
    elif item.tag == 'buyurl':
        self.Plist.append(item.text)
    elif item.tag == 'imageurl':
        self.Plist.append(item.text)
    elif item.tag == 'advertisercategory':
        self.Plist.append(item.text)
    elif item.tag=="product":
        Product(
            programname=("%s" % self.Plist[0]),
            name=("%s" % self.Plist[1]),
            description=("%s" % self.Plist[2][0:500]),
            sku=("%s" % self.Plist[3]),
            manufacturer=("%s" % self.Plist[4]),
            price=("%s" % self.Plist[5]),
            buyurl=("%s" % self.Plist[6]),
            imageurl=("%s" % self.getBigImageUrl(self.Plist[7])),
            advertisercategory=("%s" % self.Plist[8])).put()

        self.count+=1
        print self.count
        if self.count%15000 == 0:      
            time.sleep(10000)
        for ob in self.Plist:
            del ob
        del self.Plist
        self.Plist=[]
    del item

当我注释掉 Product().put() 行并运行它时,它可以通过大量行而不会对内存产生太大影响。我在中间添加睡眠的原因是我在想 GAE 产生的一些子进程正在将数据添加到数据存储中,并且可能需要一些时间来操作。所以我在添加 15000 个项目后等待,看看是否会释放任何 ram(在操作系统端也清除内存),但它没有帮助。这是我的代码中的某些内容,还是与将数据添加到数据存储区相关的某些内容。在玩了几个小时/几天后,我感到困惑和困惑。

【问题讨论】:

  • 嗯,我看代码什么都没有。我可能会在本地玩一下,看看我能不能想出点什么。在不使用大量内存的情况下迭代文件方面,您应该使用内置的生成器表达式。
  • 在 process_element() 之外调用 gc.collect() 这将强制进行垃圾收集。您的另一种选择是在您的开发盒上运行此过程,通过 remote_api 连接到 prod gae,然后您可以使用尽可能多的内存。不知道为什么你需要睡觉。也无需在循环中执行del ob。只需将 Plist 分配给新列表即可删除所有引用。再次调用 gc.collect() 将强制进行垃圾收集。请记住 python 使用引用计数,因此如果您在 process_element 之外有任何引用 Plist 中项目的内容,那么 gc 将无济于事。

标签: python google-app-engine memory-management memory-leaks google-cloud-datastore


【解决方案1】:

您是否在开发服务器中运行此代码?开发服务器的数据存储用尽内存存在一个已知问题:Why memory leaks occurs when using DataStore API on dev server。原因是它使用内存映射来存储您的所有实体。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 2015-08-24
  • 1970-01-01
相关资源
最近更新 更多