2016-02-11 16 views
5

Tôi có một tập lệnh python có thể xóa một số url. Tôi có một danh sách các url và cho mỗi url tôi nhận được html và làm một số logic với nó.Giải phóng bộ nhớ trong tập lệnh python

Tôi sử dụng Python 2.7.6 và Linux Mint 17 Quế 64 bit.

Vấn đề là đối tượng chính của tôi để cạo, mà tôi dụ cho mỗi url, không bao giờ được giải phóng khỏi bộ nhớ mặc dù không có tham chiếu đến nó. Với vấn đề đó bộ nhớ của tôi chỉ tiếp tục phát triển và phát triển nhanh chóng (vì đối tượng của tôi đôi khi rất lớn - lên đến 50MB).

Đơn giản hóa mã trông một cái gì đó như thế này:

def scrape_url(url): 
    """ 
    Simple helper method for scraping url 
    :param url: url for scraping 
    :return: some result 
    """ 
    scraper = Scraper(url) # instance main Scrape object 
    result = scraper.scrape() # scrape it 

    return result 

## SCRIPT STARTS HERE 
urls = get_urls() # fetch some list of urls 

for url in urls: 
    print 'MEMORY USAGE BEFORE SCRAPE: %s (kb)' % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 
    result = scrape_url(url) # call helper method for scraping 
    print 'MEMORY USAGE AFTER SCRAPE: %s (kb)' % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 
    print '-' * 50 

đầu ra của tôi là một cái gì đó như thế này:

MEMORY USAGE BEFORE SCRAPE: 75732 (kb) 
MEMORY USAGE AFTER SCRAPE: 137392 (kb) 
-------------------------------------------------- 
MEMORY USAGE BEFORE SCRAPE: 137392 (kb) 
MEMORY USAGE AFTER SCRAPE: 206748 (kb) 
-------------------------------------------------- 
MEMORY USAGE BEFORE SCRAPE: 206748 (kb) 
MEMORY USAGE AFTER SCRAPE: 284348 (kb) 
-------------------------------------------------- 

Cạo đối tượng là lớn và nó không được phát hành từ bộ nhớ. tôi đã cố gắng:

scraper = None 

del scraper 

hoặc thậm chí gọi gc để thu thập đối tượng với:

gc.collect() 

nhưng không giúp được gì.

Khi tôi in số tham chiếu đến đối tượng scraper với:

print sys.getrefcount(scraper) 

tôi nhận được mà tôi nghĩ có nghĩa là không có tài liệu tham khảo khác để phản đối và cần được làm sạch bằng gc.

Đối tượng Scraper có rất nhiều subobject. Có thể là một số tài liệu tham khảo phụ của đối tượng có được trái một nơi nào đó và vì lý do đó gc không thể phát hành đối tượng Scaper chính hoặc có một số lý do khác tại sao python không phát hành bộ nhớ?

Tôi tìm thấy một số chủ đề về vấn đề này trong SO và một số các câu trả lời mà họ đang nói bộ nhớ mà không thể được phát hành trừ khi bạn đang sinh sản/giết chết tiến trình con mà âm thanh thực sự kỳ lạ (LINK)

Cảm ơn, Ivan

+1

"Đối tượng scraper có nhiều nội dung con ... không phát hành bộ nhớ?" đó sẽ là lý do chính đáng duy nhất. scrape url thiết lập một kết nối trên một cổng tôi giả sử? Có lẽ kết nối đó giữ tham chiếu đứng. – user2255757

+0

bạn có chắc chắn rằng kết quả không được kết nối với scrapper? – Jerzyk

Trả lời

1

Bạn đang sử dụng trình lặp, bộ nhớ phải luôn ở trong bộ nhớ. Viết lại vòng lặp của bạn để sử dụng máy phát điện và xóa bỏ một cách lười biếng. Nội dung nào đó dọc theo dòng:

def gen(): 
     for i in xrange(0, len(urls)): 
      yield urls[i] 
+1

hoặc biểu thức trình tạo với gen = (url cho url trong url) – Marcin

Các vấn đề liên quan