2011-11-06 32 views

Trả lời

23

Cơ chế tính tham chiếu chuẩn của Python không thể chu kỳ miễn phí, do đó cấu trúc trong ví dụ của bạn sẽ bị rò rỉ.

Các supplemental garbage collection facility, tuy nhiên, được kích hoạt theo mặc định và sẽ có thể giải phóng cấu trúc đó, nếu không ai trong số các thành phần của nó có thể truy cập từ bên ngoài nữa và họ không có phương pháp __del__().

Nếu có, trình thu gom rác will not free them vì không thể xác định một lệnh an toàn để chạy các phương thức __del__() này.

+5

Cần nêu rõ rằng GC bạn gọi là "bổ sung" được bật theo mặc định trong Python –

+0

@Eli, bạn nói đúng, câu trả lời được cập nhật tương ứng. –

+3

Hoan hô! Ít nhất, các dân tộc (bạn và Raymond Hettinger) không gây nhầm lẫn về GC và truy cập refs và những người không sử dụng "thu gom rác" là từ đồng nghĩa của "cơ chế đếm tham chiếu"! Tôi đã lúng túng trong một thời gian dài về việc tôi đã hiểu những điều như thế nhưng tôi đã liên tục đọc những bản văn trong đó người dân bày tỏ ý tưởng của mình như thể GC chịu trách nhiệm về việc giết hại những vật thể không được tham chiếu. Trong câu trả lời của bạn, sự khác biệt là hoàn toàn thể hiện và rõ ràng. Cảm ơn bạn. Do đó +1 – eyquem

5

GC Python được thiết kế để đi qua tất cả các đối tượng trực tiếp để xác định vị trí và loại bỏ chu kỳ tài liệu tham khảo không có tài liệu tham khảo bên ngoài.

Bạn có thể xác thực đó là những gì đang xảy ra bằng cách chạy gc.collect() và sau đó in gc.garbagegc.get_objects.

2

Nếu bạn sử dụng weakrefs cho con trỏ cha mẹ của bạn, sau đó GC sẽ xảy ra bình thường.

18

Để mở rộng câu trả lời của Frédéric một chút, the "reference counts" section tài liệu giải thích phát hiện chu trình bổ sung độc đáo.

Kể từ khi tôi tìm thấy giải thích việc một cách tốt để xác nhận tôi hiểu nó, sau đây là một số ví dụ ... Với hai loại cổ phiếu này:

class WithDel(object): 
    def __del__(self): 
     print "deleting %s object at %s" % (self.__class__.__name__, id(self)) 


class NoDel(object): 
    pass 

Tạo một đối tượng và làm mất tài liệu tham khảo từ a gây nên các phương pháp __del__ , nhờ vào ref đếm:

>>> a = WithDel() 
>>> a = None # leaving the WithDel object with no references 
deleting WithDel object at 4299615184 

Nếu chúng ta thực hiện một vòng lặp tham khảo giữa hai vật không có phương pháp__del__, tất cả vẫn còn rò rỉ-miễn phí, t thời gian của mình nhờ vào việc phát hiện chu kỳ.Đầu tiên, cho phép đầu ra thu gom rác debug:

>>> import gc 
>>> gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_OBJECTS) 

Sau đó thực hiện một vòng lặp tham khảo giữa hai đối tượng:

>>> a = NoDel(); b = NoDel() 
>>> a.other = b; b.other = a # cyclical reference 
>>> a = None; b = None # Leave only the reference-cycle 
>>> gc.collect() 
gc: collectable <NoDel 0x10046ed50> 
gc: collectable <NoDel 0x10046ed90> 
gc: collectable <dict 0x100376c20> 
gc: collectable <dict 0x100376b00> 
4 
>>> gc.garbage 
[] 

(các dict là từ các đối tượng nội __dict__ thuộc tính)

Tất cả là tốt, cho đến thậm chí một trong các đối tượng trong chu kỳ có chứa phương thức __del__:

>>> a = NoDel(); b = WithDel() 
>>> a.other = b; b.other = a 
>>> a = None; b = None 
>>> gc.collect() 
gc: uncollectable <WithDel 0x10046edd0> 
gc: uncollectable <dict 0x100376b00> 
gc: uncollectable <NoDel 0x10046ed90> 
gc: uncollectable <dict 0x100376c20> 
4 
>>> gc.garbage 
[<__main__.WithDel object at 0x10046edd0>] 

Như Phaolô đã đề cập, các vòng lặp có thể được chia với một weakref:

>>> import weakref 
>>> a = NoDel(); b = WithDel() 
>>> a.other = weakref.ref(b) 
>>> b.other = a # could also be a weakref 

Sau đó, khi b tham chiếu đến đối tượng WithDel bị mất, nó bị xóa, mặc dù chu kỳ:

>>> b = None 
deleting WithDel object at 4299656848 
>>> a.other 
<weakref at 0x10045b9f0; dead> 

Ồ, objgraph sẽ có ích indicated the problematic __del__ method like this

+0

Điều này làm việc cho tôi trong python2, tuy nhiên, trong python3 tôi không thể tái tạo rò rỉ ... Có gì thay đổi không? – kralyk

+0

@kralyk Tôi đoán pep này có trách nhiệm: https://www.python.org/dev/peps/pep-0442/ – ead

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