Tóm lược. trong hướng dẫn này, bạn sẽ tìm hiểu cách thức hoạt động của trình thu gom rác Python và cách tương tác với trình thu gom rác theo chương trình
Giới thiệu về bộ sưu tập rác Python
Trong C/C++, bạn hoàn toàn chịu trách nhiệm quản lý bộ nhớ của chương trình. Tuy nhiên, trong Python, bạn không phải tự quản lý bộ nhớ vì Python đã tự động làm việc đó cho bạn
Trong phần hướng dẫn về tài liệu tham khảo, bạn đã học được rằng Trình quản lý bộ nhớ Python theo dõi các tài liệu tham khảo của các đối tượng. Trình quản lý bộ nhớ hủy đối tượng và lấy lại bộ nhớ sau khi số lượng tham chiếu của đối tượng đó bằng 0
Tuy nhiên, việc đếm tham chiếu không phải lúc nào cũng hoạt động bình thường. Ví dụ: khi bạn có một đối tượng tham chiếu chính nó hoặc hai đối tượng tham chiếu lẫn nhau. Điều này tạo ra một thứ gọi là tham chiếu vòng tròn
Khi Trình quản lý bộ nhớ Python không thể xóa các đối tượng có tham chiếu vòng tròn, nó sẽ gây rò rỉ bộ nhớ
Đây là lý do tại sao trình thu gom rác ra đời để sửa các tham chiếu vòng tròn
Python cho phép bạn tương tác với trình thu gom rác thông qua mô-đun
5 tích hợpCode language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Tương tác với trình thu gom rác Python
Trong ví dụ này, trước tiên chúng ta sẽ tạo một tham chiếu vòng giữa hai thể hiện của lớp A và lớp B. Sau đó, chúng tôi sử dụng trình thu gom rác để hủy các đối tượng trong tham chiếu vòng tròn
Đầu tiên, nhập mô-đun
5 vàCode language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
7 và xác định hai chức năng để đếm tham chiếu và kiểm tra xem đối tượng có tồn tại trong bộ nhớ khôngCode language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Code language: Python [python]
import gc import ctypes def ref_count[address]: return ctypes.c_long.from_address[address].value def object_exists[object_id]: for object in gc.get_objects[]: if id[object] == object_id: return True return False
Trong mã này,
8 trả về số lượng tham chiếu của một đối tượng được chỉ định bởi địa chỉ bộ nhớ của nó. Và hàmCode language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
9 trả vềCode language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
0 nếu một đối tượng tồn tại trong bộ nhớCode language: Python [python]
gc.disable[]
Thứ hai, tạo hai lớp
1 vàCode language: Python [python]
gc.disable[]
2 có tham chiếu lẫn nhauCode language: Python [python]
gc.disable[]
Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Thứ ba, vô hiệu hóa bộ thu gom rác bằng cách gọi hàm
3Code language: Python [python]
gc.disable[]
gc.disable[]
Code language: Python [python]
Thứ tư, tạo một thể hiện mới của lớp A cũng tự động tạo một thể hiện mới của B
2Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
đầu ra
3Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Thứ năm, xác định hai biến để giữ địa chỉ bộ nhớ của các thể hiện của A và B. Các biến này theo dõi địa chỉ bộ nhớ của các thể hiện của A và B khi biến
4 tham chiếu đến một đối tượng khácCode language: Python [python]
gc.disable[]
5Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Thứ sáu, hiển thị số lượng tham chiếu của các phiên bản của A và B
6Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Thể hiện của A có hai tham chiếu là biến
4 và thể hiện của B. Và thể hiện của B có một tham chiếu là thể hiện của ACode language: Python [python]
gc.disable[]
Thứ bảy, kiểm tra xem cả hai trường hợp của A và B có trong bộ nhớ không
8Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Cả hai đều tồn tại
Thứ tám, đặt một biến thành
6Code language: Python [python]
gc.disable[]
0Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Thứ chín, lấy số tham chiếu của thể hiện của A và B
1Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Bây giờ, cả hai số tham chiếu của phiên bản A và B là 1
Thứ mười, kiểm tra xem các trường hợp tồn tại
8Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Cả hai vẫn tồn tại như mong đợi
Thứ mười một, bắt đầu thu gom rác
1Code language: Python [python]
class A: def __init__[self]: self.b = B[self] print[f'A: {hex[id[self]]}, B: {hex[id[self.b]]}'] class B: def __init__[self, a]: self.a = a print[f'B: {hex[id[self]]}, A: {hex[id[self.a]]}']
Khi trình thu gom rác chạy, nó có thể phát hiện tham chiếu vòng tròn, hủy các đối tượng và lấy lại bộ nhớ