2011-06-30 29 views
5
import json 
import time 
from itertools import count 

def keygen(size): 
    for i in count(1): 
     s = str(i) 
     yield '0' * (size - len(s)) + str(s) 

def jsontest(num): 
    keys = keygen(20) 
    kvjson = json.dumps(dict((keys.next(), '0' * 200) for i in range(num))) 
    kvpairs = json.loads(kvjson) 
    del kvpairs # Not required. Just to check if it makes any difference        
    print 'load completed' 

jsontest(500000) 

while 1: 
    time.sleep(1) 

top cho biết rằng quá trình python chứa ~ 450Mb RAM sau khi hoàn thành chức năng 'jsontest'. Nếu cuộc gọi tới 'json.loads' bị bỏ qua thì vấn đề này không được quan sát. A gc.collect sau khi thực hiện chức năng này sẽ giải phóng bộ nhớ.Nêu nhớ bộ nhớ json của Python

Có vẻ như bộ nhớ không được giữ trong bất kỳ bộ nhớ đệm hoặc bộ cấp phát bộ nhớ trong của python như lời gọi rõ ràng tới gc.collect đang giải phóng bộ nhớ.

Điều này có xảy ra do ngưỡng thu gom rác thải (700, 10, 10) chưa bao giờ đạt được?

Tôi đã đặt một số mã sau jsontest để mô phỏng ngưỡng. Nhưng nó không giúp được gì.

Trả lời

2

Đặt này ở đầu chương trình của bạn

import gc 
gc.set_debug(gc.DEBUG_STATS) 

và bạn sẽ nhận được in ra bất cứ khi nào có một bộ sưu tập. Bạn sẽ thấy rằng trong mã ví dụ của bạn, không có bộ sưu tập nào sau khi hoàn thành jsontest cho đến khi chương trình thoát.

Bạn có thể đặt

print gc.get_count() 

để xem số lượng hiện tại. Số đầu tiên là số lượng phân bổ vượt quá phân bổ so với bộ sưu tập cuối cùng của thế hệ 0; thứ hai (số thứ ba) là số lần tạo ra 0 (resp. 1) đã được thu thập kể từ lần thu thập cuối cùng của thế hệ 1 (resp. 2). Nếu bạn in chúng ngay lập tức sau khi jsontest hoàn thành, bạn sẽ thấy rằng số lượng là (548, 6, 0) hoặc một cái gì đó tương tự (không có nghi ngờ điều này thay đổi theo phiên bản Python). Vì vậy, ngưỡng không đạt được và không có bộ sưu tập đã diễn ra.

Đây là hành vi điển hình cho lập lịch thu thập rác dựa trên ngưỡng. Nếu bạn cần bộ nhớ trống để được trả về hệ điều hành một cách kịp thời, thì bạn cần phải kết hợp lập lịch dựa trên ngưỡng với lập lịch dựa trên thời gian (nghĩa là, yêu cầu một bộ sưu tập khác sau một khoảng thời gian nhất định kể từ khi bộ sưu tập cuối cùng , ngay cả khi chưa đạt đến ngưỡng này).

+0

Thậm chí nếu chúng tôi gọi jsontest nhiều lần, bộ nhớ vẫn ở mức ~ 450MB. Đây có phải là bộ nhớ được sử dụng bởi cuộc gọi jsontest cuối cùng? Mã này là một phần của webapp xử lý các thông điệp json. Ngay cả sau khi chạy webapp trong một giờ, bộ nhớ dường như không được phát hành. Có cách giải quyết nào khác ngoài gc.collect không? – Anoop

+1

Thử in 'gc.get_count()' sau mỗi cuộc gọi thành 'jsontest' và tất cả sẽ rõ ràng. Ngoài ra, có gì sai khi gọi 'gc.collect'? –

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