2014-01-17 28 views
2

我有一個腳本,我正在使用它來構建一個站點地圖 - 對於每個相關模型,我生成了一些帶有每個對象的URL的分頁站點地圖,每個一週我打算再次運行該腳本以重新生成新數據的站點地圖。使用Django的Python腳本中的內存泄漏

但是,當我在我的Ubuntu服務器上運行此腳本時,內存使用量不斷攀升,直到該進程最終被操作系統終止。下面是我目前遇到問題通過獲取功能:

def xml_for_page(object): 
    sOutText = "\t<url>\n" 

    sURL = object.url() 
    sOutText += "\t\t<loc>http://www.mysite.com%s</loc>\n" % sURL 

    sLastModified = object.last_status_change.isoformat() 
    sOutText += "\t\t<lastmod>%s</lastmod>\n" % sLastModified 

    sChangeFreq = "monthly" 
    sOutText += "\t\t<changefreq>%s</changefreq>\n" % sChangeFreq 

    sOutText += "\t</url>\n" 

    return sOutText 

def generate_object_map(): 

    # Do this in chunks of ITEMS_PER_FILE 
    bFinished = False 
    iOffset = 0 
    iCurrentPage = 0 

    while not bFinished: 
     objResults = PageObject.objects.filter(submission_status=SUBMISSION_STATUS_ACCEPTED).order_by('-popularity')[iOffset:iOffset+ITEMS_PER_FILE] 
     if objResults.count() < 1: 
      break 
     sFilename = "%s/sitemap-objects-%i.xml" % (OUTPUT_DIR, iCurrentPage) 
     fObjects = open(sFilename, 'w') 
     fObjects.write('<?xml version="1.0" encoding="UTF-8"?>\n') 
     fObjects.write('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n') 
     for object in objResults: 
      fObjects.write(xml_for_page(object)) 
     fObjects.write('</urlset>') 
     fObjects.close() 
     iOffset += ITEMS_PER_FILE 
     iCurrentPage += 1 

那麼,什麼是怎麼回事是:while not bFinished循環的每次迭代,我們創造了我們在頁面上一個新的文件,並查詢數據庫該特定的一組對象。然後,我們遍歷這些對象並將該頁面的XML寫入站點地圖文件。一旦這些文件被寫入,我們關閉該文件並開始另一個文件。此分頁行爲的原因是,將所有條目寫入一個文件時,我很快就達到了內存限制。這表現比它更好,但是當我使用resource來跟蹤內存使用情況時,我可以看到它在每個文件寫入後都在攀升。在數據庫中有大約20萬個這種類型的對象,所以理想情況下我需要儘可能地擴展它。但是我無法看到主循環的每次迭代之後內存如何保留:在每次迭代之後重寫對象QuerySet,並且在每次迭代之後關閉並重新分配文件句柄。我認爲一旦變量被重新分配,Python的GC行爲將允許不再使用的對象被清除。情況並非如此嗎?

+0

能'object.url()'做某事嗎?如果只用一組字符串替換django模型,並將其寫入文件,以查看模型或您的'xml_for_page'是否與它有任何關係,那該怎麼辦?繼續削減示例代碼,正如我所說 – TankorSmash

+0

如果您要提高可伸縮性,爲什麼不在模型上使用'.defer'或'.only'或者甚至是'.values_list'?降低數據庫調用的數量越多越好。 – TankorSmash

+0

'url()'函數在這裏限制了我 - 雖然我可以通過values_list獲取ID和last_modified_date,但url函數使用來自外鍵字段的值,所以我仍然需要獲取對象本身。或者是否有類似的函數來獲取某個特定成員函數的結果? – benwad

回答

1

The docs似乎暗示可以使用object.values_list('foreignobject__url'),它允許相關的字段。因此,如果foreignobject是模型上的外鍵,其本身包含字段url,則可以安全使用values_list以減少數據庫調用。