Python xử lý bộ nhớ như thế nào?

Đ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õ động

Trong 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 heap
y == 100 // this will not create a new object as an object with value 100 is already available on heap
print(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ượng

Khi 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ượng

Theo 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ẻ

Python xử lý các vấn đề về bộ nhớ như thế nào?

Bạn sẽ phải gỡ lỗi sử dụng bộ nhớ trong Python bằng mô-đun có sẵn trình thu gom rác . Điều đó sẽ cung cấp cho bạn một danh sách các đối tượng được người thu gom rác biết đến. Gỡ lỗi cho phép bạn xem phần lớn bộ nhớ lưu trữ Python đang được áp dụng. Sau đó, bạn có thể tiếp tục và lọc mọi thứ dựa trên mức sử dụng.

Python theo dõi bộ nhớ như thế nào?

Làm việc với Python Memory Profiler . Bạn sẽ thấy mức sử dụng bộ nhớ theo từng dòng sau khi tập lệnh của bạn thoát. putting the @profile decorator around any function or method and running python -m memory_profiler myscript. You'll see line-by-line memory usage once your script exits.

Python lưu trữ dữ liệu trong bộ nhớ như thế nào?

Có thể lưu trữ trạng thái của đối tượng Python dưới dạng luồng byte trực tiếp vào tệp hoặc luồng bộ nhớ và truy xuất về trạng thái ban đầu. This process is called serialization and de-serialization. Python's built in library contains various modules for serialization and deserialization process.

Python xóa bộ nhớ như thế nào?

Bộ nhớ Heap trong Python chứa các đối tượng và các cấu trúc dữ liệu khác được sử dụng trong chương trình. Vì vậy, khi một biến (tham chiếu đến một đối tượng) không còn được sử dụng, trình quản lý bộ nhớ Python sẽ giải phóng dung lượng, tôi. e. nó xóa đối tượng không cần thiết .