2013-12-10 14 views
16

Pythons gc.disable vô hiệu hóa thu gom rác tự động. Như tôi đã hiểu, điều đó sẽ có một số tác dụng phụ. Tại sao bất cứ ai muốn vô hiệu hóa bộ sưu tập rác tự động, và làm thế nào có thể quản lý một cách hiệu quả bộ nhớ mà không có nó?Tại sao vô hiệu hóa bộ thu gom rác?

Trả lời

16

Một cách sử dụng để vô hiệu hóa bộ thu gom rác là nhận được kết quả phù hợp hơn khi định thời gian thực hiện mã. The timeit module thực hiện việc này.

def timeit(self, number=default_number): 
    if itertools: 
     it = itertools.repeat(None, number) 
    else: 
     it = [None] * number 
    gcold = gc.isenabled() 
    gc.disable() 
    ... 

In Python2 và lên đến Python3.2gc.disable() cũng được sử dụng để tránh a bug caused by garbage collection occurring between fork and exec. Vấn đề dường như đã được sửa trong Python3.3 mà không cần gọi gc.disable().

3

Một use-case sẽ tự kiểm soát thu gom rác thải với gc.collect()

+0

Nhưng vô hiệu hóa GC trước tiên là một yêu cầu để có thể sử dụng 'gc.collect()'? Hoặc một trường hợp sử dụng cho 'gc.collect()' là gì? (lưu ý: Tôi thực sự có trường hợp sử dụng như vậy trong quá khứ trong một ứng dụng C# đã hết bộ nhớ trong một hộp <512MiB) –

+0

Không. Bạn có thể gọi '' gc.collect() '' bất kỳ lúc nào AFAIK. –

6

Từ trang cùng bạn liên kết đến:

Kể từ khi nhà sưu tập bổ sung các tính tham khảo đã được sử dụng trong Python, bạn có thể vô hiệu hóa bộ thu nếu bạn chắc chắn chương trình của bạn không tạo chu trình tham chiếu.

Vì vậy, câu trả lời cho phần thứ hai của câu hỏi, "cách quản lý bộ nhớ hiệu quả mà không có bộ nhớ". Không tạo chu trình tham chiếu. Đó là một trường hợp sử dụng khá hạn chế, chắc chắn.

Đối với phần đầu tiên của câu hỏi, câu trả lời là hiệu suất. Một lần nữa, một trường hợp sử dụng khá hạn chế. Vô hiệu hóa GC sẽ chỉ giúp nếu (a) GC thực sự đang làm việc, và (b) công việc đó không đạt được gì, nghĩa là không tìm thấy gì miễn phí, hoặc tìm kiếm quá ít đến mức bạn nghĩ chương trình của mình có thể chịu đựng sự rò rỉ miễn là GC bị vô hiệu hóa. Vì vậy, nếu chương trình của bạn quá chậm và không tạo chu trình tham chiếu và vô hiệu hóa GC xuất hiện để tăng tốc độ, thì bạn sẽ xem xét tắt GC.

Tôi suy đoán (dựa trên GC trước đó mà tôi đã thấy, không phải của Python nói riêng) nếu bạn không phân bổ bộ nhớ nào thì bộ thu gom rác sẽ không có bất kỳ chi phí hiệu suất dài hạn nào. Nó có thể có một số chi phí ngắn hạn và không thể đoán trước làm rõ những gì đã đi trước đó. Vì vậy, ngay cả trong trường hợp bạn đang đi vào một thói quen crunching số numpy lớn và nghĩ rằng bạn nên xem xét để bóp tất cả các hiệu suất có thể ra khỏi phần đó của mã, vô hiệu hóa GC trong khi bạn làm điều đó vẫn sẽ không giúp đỡ. Nó sẽ chỉ trì hoãn chi phí thời gian làm sạch các chu kỳ tham chiếu trước đó cho đến sau khi bạn kích hoạt lại GC.

Có thể cho rằng, các chương trình chạy trong một thời gian ngắn và không sử dụng nhiều bộ nhớ không cần thu gom rác, chúng có thể chịu được rò rỉ. Nhưng thậm chí nhiều hơn cho là, nếu bạn bắt đầu nghĩ như thế bạn cuối cùng sẽ gặp rắc rối với một chương trình làm rò rỉ nhiều bộ nhớ hơn bạn mong đợi.

+0

Vấn đề là, trên thực tế, rất khó (đường biên không thể) để đảm bảo bạn không có chu kỳ tham chiếu. Bạn có thể dễ dàng đảm bảo mã của mình không, nhưng còn phụ thuộc của bạn thì sao? Vì mô-đun, hàm và lớp thường không chỉ định nếu chúng tạo chu kỳ tham chiếu, bạn sẽ phải trải qua mã của mọi phụ thuộc và phụ thuộc chuyển tiếp (bao gồm thư viện chuẩn) và xác minh rằng không có tham chiếu nào được thực hiện. Và tất nhiên, việc nâng cấp một phụ thuộc có thể giới thiệu một chu kỳ. – Kevin

+0

@Kevin: tuyệt đối. Tôi nghĩ rằng tôi dự định "khá hạn chế" là một cách nói mỉa mai. –

5

Sự cố với GC được bật luôn là bạn không biết khi điều đó sẽ xảy ra. Vì vậy, nếu (một phần của) chương trình của bạn là thời gian quan trọng, cần thời gian thực, vv, sau đó bạn có thể vô hiệu hóa GC cho thời gian (một phần của) chương trình của bạn chạy.

Cho dù bạn muốn bật lại GC tự động sau này hoặc nếu bạn muốn thực hiện thủ công một cách thủ công bằng cách gọi gc.collect() là không quan tâm đến câu hỏi đó.

Ngoài ra, một số chương trình được thiết kế để chạy chỉ trong một thời gian rất ngắn, do đó nhà phát triển có thể đảm bảo rằng không thể xảy ra bất kỳ vấn đề bộ nhớ nào trong thời gian đó (xem xét các chương trình như ls); sau đó toàn bộ khía cạnh GC có thể được bỏ qua có lợi cho hiệu suất.