Điều rất quan trọng đối với bất kỳ nhà phát triển phần mềm nào là hiểu cách phân bổ bộ nhớ xảy ra và cách quản lý bộ nhớ đó
Trong này chúng ta sẽ đi qua
- Quản lý bộ nhớ là gì?
- Tại sao quản lý bộ nhớ là cần thiết?
- Bộ nhớ được phân bổ như thế nào trong Python?
- Thu gom rác bằng Python
Quản lý bộ nhớ là gì?
Quản lý bộ nhớ theo thuật ngữ đơn giản có nghĩa là, quá trình cung cấp bộ nhớ cần thiết cho chương trình của bạn để lưu trữ dữ liệu và giải phóng dữ liệu không sử dụng trong bộ nhớ được gọi là quản lý bộ nhớ
Cung cấp bộ nhớ được gọi là cấp phát bộ nhớ. Giải phóng bộ nhớ được gọi là giải phóng bộ nhớ
Trong Python, Trình quản lý bộ nhớ chịu trách nhiệm cấp phát và hủy cấp phát bộ nhớ
Tại sao quản lý bộ nhớ là cần thiết?
Nói chung, các ngôn ngữ lập trình sử dụng các đối tượng để thao tác trên dữ liệu mà chương trình của bạn yêu cầu. Các đối tượng này được tạo trong bộ nhớ để truy cập nhanh hơn. Vì vậy, khi một đối tượng được tạo, nó sẽ được phân bổ một số dung lượng trên bộ nhớ, sau khi chương trình của bạn hoàn thành việc thực thi, các đối tượng này phải được dọn sạch hoặc xóa khỏi bộ nhớ vì chúng không còn được sử dụng nữa và có thể được sử dụng lại cho các quy trình khác/
Nếu những đối tượng không sử dụng này không được dọn sạch thì bộ nhớ của bạn có thể bị đầy và sẽ không có đủ dung lượng cho các chương trình khác và ứng dụng của bạn có thể bị sập. Vì vậy, quản lý bộ nhớ là rất quan trọng trong bất kỳ ngôn ngữ lập trình nào
Trong các ngôn ngữ lập trình ban đầu (như C), các nhà phát triển có trách nhiệm cấp phát bộ nhớ và hủy cấp phát bộ nhớ sau khi thực thi dẫn đến các vấn đề dưới đây
Quên giải phóng bộ nhớ — Nếu nhà phát triển quên giải phóng bộ nhớ chưa sử dụng, thì bộ nhớ có thể bị đầy dẫn đến chương trình của bạn sử dụng quá nhiều bộ nhớ
Giải phóng bộ nhớ đã được sử dụng — Nếu nhà phát triển vô tình giải phóng bộ nhớ đang được sử dụng, điều này gây ra sự cố khi chương trình của bạn cố gắng truy cập vào cùng một bộ nhớ dẫn đến hành vi không mong muốn
Vì vậy, những vấn đề này đã khiến các ngôn ngữ lập trình mới triển khai Quản lý bộ nhớ và Thu gom rác tự động, được xử lý bởi Trình quản lý bộ nhớ Python trong Python.
Trong phân bổ bộ nhớ python và phân bổ lại là tự động
Bộ nhớ được phân bổ như thế nào trong Python?
Vì vậy, như đã nói trong trình quản lý bộ nhớ python chịu trách nhiệm phân bổ và hủy phân bổ bộ nhớ
Bộ nhớ có 2 phần stack memory và heap memory (không liên quan gì đến cấu trúc dữ liệu heap)
Bộ nhớ ngăn xếp —tất cả các phương thức/cuộc gọi phương thức, các tham chiếu được lưu trữ trong bộ nhớ ngăn xếp
Bộ nhớ heap - tất cả các đối tượng được lưu trữ trong heap
Mọi thứ trong python đều là một Đối tượng. Vì vậy, điều rất quan trọng là phải hiểu về các đối tượng trong python
Python là ngôn ngữ được nhập động, có nghĩa là các loại được gán dựa trên giá trị mà nó đề cập đến không giống như các ngôn ngữ lập trình khác (Java và C#)
Ví dụ: trong các ngôn ngữ lập trình khác như Java/C#, bạn không thể tạo biến mà không chỉ định loại cho biến đó
In C# we create a variable as , public int <variable_name>
Ngôn ngữ gõ độngTrong ví dụ trên, tôi đã tạo một biến có tên “x” ban đầu được gán cho Không có. (None trong python tương đương với null trong các ngôn ngữ lập trình khác). Khi “x” được gán cho “None” , loại “x” là “None”
Khi “x” được gán lại cho 10 , kiểu của “x” là “int'
Khi “x” được gán lại thành “10”, loại “x” là “str”
Không giống như các ngôn ngữ lập trình khác, trong python bất cứ khi nào một biến được gán một giá trị, trình quản lý bộ nhớ python sẽ kiểm tra xem một đối tượng có giá trị đó đã có sẵn trong bộ nhớ chưa. Nếu đối tượng đã có trong bộ nhớ, thì biến này trỏ đến đối tượng đó thay vì tạo đối tượng mới có cùng giá trị
Nếu đối tượng có giá trị đó không có sẵn trong bộ nhớ (heap), trình quản lý bộ nhớ python sẽ tạo một đối tượng mới với giá trị đã chỉ định và biến này sẽ trỏ đến đối tượng mới được tạo này trên heap (bộ nhớ)
Ngoài ra, khi một biến được gán lại với biến mới, thay vì ghi đè giá trị trong bộ nhớ, những gì python làm là, nó sẽ lại thực hiện theo quy trình tương tự như trên và kiểm tra xem có đối tượng nào đã có trên heap với giá trị mới không. Nếu đối tượng đã có mặt, thì biến này sẽ trỏ đến đối tượng đó, nếu không, trình quản lý bộ nhớ python sẽ tạo một đối tượng mới trên heap với giá trị mới và biến này sẽ trỏ đến giá trị đó
Ví dụ,
x == 100 // this will create a new object in heapy == 100 // this will not create a new object as an object with value 100 is already available on heapprint(id(x) == id(y)) // this returns true because x and y are pointing to same object on heapx = 101 // now when new value is assigned "101" is not available on heap , so new object is created and x points to this new object . In this case value at that location is not overwritten unlike other programming languages.
Điều này không xảy ra với các ngôn ngữ lập trình khác khi một biến được cập nhật, giá trị tại vị trí/địa chỉ bộ nhớ đó được ghi đè bằng giá trị cập nhật mới
Để hiểu rõ về các điểm đã thảo luận ở trên, vui lòng nhấp vào liên kết bên dưới thể hiện các điểm đã thảo luận ở trên về phân bổ bộ nhớ đối tượng python
tạo đối tượngKhi một đối tượng mới được tạo trong python, trình quản lý bộ nhớ python đảm bảo rằng có đủ bộ nhớ trong heap để phân bổ không gian cho đối tượng đó
Trong python, tất cả các đối tượng đều bắt nguồn từ PyObject, một cấu trúc có hai thuộc tính tham chiếu đếm và con trỏ tới đối tượng
Để biết thêm thông tin về PyObject, hãy tham khảo tài liệu bên dưới
Cấu trúc đối tượng chung - Python 3. 9. 6 tài liệu
Có một số lượng lớn các cấu trúc được sử dụng trong định nghĩa các loại đối tượng cho Python. Phần này…
tài liệu. con trăn. tổ chức
Thu gom rác bằng Python
Bây giờ, đã đến lúc dọn dẹp những đồ vật không dùng đến. Quá trình phân bổ lại bộ nhớ hoặc xóa các đối tượng không sử dụng để có thể cung cấp cho các đối tượng khác được gọi là Bộ sưu tập rác
Vì vậy, công việc của bộ thu gom rác là theo dõi các đối tượng có thể hủy phân bổ
Python sử dụng 2 thuật toán dưới đây để thu gom rác
- đếm tham chiếu
- thu gom rác thế hệ
Đếm tham chiếu
Đếm tham chiếu là một kỹ thuật đơn giản trong đó, bất cứ khi nào số lượng tham chiếu của một đối tượng đạt đến “0”, thì đối tượng đó đủ điều kiện để thu gom rác và bộ nhớ được phân bổ cho đối tượng đó sẽ tự động được phân bổ lại
Bất cứ khi nào một đối tượng được tạo, số lượng tham chiếu của đối tượng đó sẽ tăng lên “1” và tương tự, khi một tham chiếu đến đối tượng đó bị xóa, thì số lượng tham chiếu của nó sẽ giảm đi “1”. Cuối cùng, khi số lượng tham chiếu của đối tượng đó trở thành “0”, bộ nhớ được phân bổ cho đối tượng đó sẽ bị hủy phân bổ
Mô-đun “sys” của Python, cung cấp một phương thức gọi là “getrefcount(object)”, cung cấp số lượng tham chiếu cho một đối tượng nhất định
Đi qua ví dụ mã bên dưới để chứng minh, trong tình huống nào số lượng tham chiếu của một đối tượng tăng và giảm
Số tham chiếu đối tượngTheo mặc định, python sử dụng kỹ thuật đếm tham chiếu để thu gom rác, không thể tắt kỹ thuật này (nhà phát triển không có quyền kiểm soát đối với nó)
Nhưng vấn đề với kỹ thuật này là nó có một số chi phí hoạt động bởi vì, mọi đối tượng phải theo dõi số lượng tham chiếu để phân bổ lại bộ nhớ và việc phân bổ lại bộ nhớ xảy ra bất cứ khi nào số lượng tham chiếu đối tượng trở thành "0"
Việc đếm tham chiếu sẽ không thể phát hiện các tham chiếu theo chu kỳ và các đối tượng đó sẽ không đủ điều kiện để thu gom rác
Vì những vấn đề trên, python còn sử dụng một kỹ thuật khác có tên là Generational Garbage Collection.
Thu gom rác thế hệ
Đây cũng là một quy trình tự động trong python, nhưng không giống như việc đếm tham chiếu không thể bị vô hiệu hóa, bộ sưu tập rác thế hệ là tùy chọn và cũng có thể được kích hoạt theo cách thủ công
mô-đun gc trong python chịu trách nhiệm thu gom rác thế hệ
Trong kỹ thuật này, tất cả các đối tượng python được phân thành 3 loại
- thế hệ 0
- thế hệ 1
- thế hệ 2
Mỗi thế hệ có một ngưỡng được xác định trước, ngưỡng không là gì nhưng nó là một chỉ báo cho trình thu gom rác khi gọi trình thu gom rác
Bạn có thể kiểm tra ngưỡng mặc định bằng cách nhập mô-đun gc như bên dưới
Bạn cũng có thể kiểm tra số lượng đối tượng trong mỗi thế hệ như bên dưới
Bạn cũng có thể tự gọi bộ sưu tập rác như bên dưới
Bạn cũng có thể đặt ngưỡng như bên dưới
Khi một đối tượng mới được tạo ra, đối tượng đó được xếp vào “thế hệ 0”
Bộ sưu tập rác được kích hoạt tự động khi một thế hệ đạt đến ngưỡng của nó và bất kỳ đối tượng nào còn lại trong thế hệ đó sau khi bộ sưu tập rác được nâng cấp lên thế hệ cũ hơn
Nếu có 2 thế hệ đạt đến ngưỡng, bộ sưu tập rác luôn chọn thế hệ cũ và sau đó là thế hệ trẻ