Có nên xóa ironpython trong ổ window

Ngay cả tôi cũng gặp vấn đề tương tự khi hiểu CPython, JPython, IronPython, PyPy khác nhau như thế nào.

Vì vậy, tôi sẵn sàng làm rõ ba điều trước khi bắt đầu giải thích:

  1. Python: Đây là một ngôn ngữ, nó chỉ nêu/mô tả cách truyền đạt/thể hiện bản thân với người phiên dịch (chương trình chấp nhận mã python của bạn).
  2. Thực hiện: Tất cả là về cách người phiên dịch được viết, cụ thể, bằng ngôn ngữ nàonhững gì nó kết thúc làm.
  3. Bytecode: Đó là mã được xử lý bởi một chương trình, thường được gọi là máy ảo, thay vì máy tính "thực", bộ xử lý phần cứng.

CPython là việc thực hiện, đó là viết bằng ngôn ngữ C. Nó kết thúc việc tạo mã byte (stack-machine Tập lệnh dựa trên) là đặc trưng của Python và sau đó thực thi nó . Lý do để chuyển đổi mã Python thành mã byte là bởi vì nó dễ dàng hơn thực hiện một trình thông dịch nếu nó trông giống như hướng dẫn máy. Nhưng, không cần thiết phải tạo một số mã byte trước khi thực hiện Mã Python (nhưng CPython không sản xuất).

Nếu bạn muốn xem mã byte của CPython thì bạn có thể. Đây là cách bạn có thể:

>>> def f(x, y):                # line 1
...    print("Hello")           # line 2
...    if x:                    # line 3
...       y += x                # line 4
...    print(x, y)              # line 5
...    return x+y               # line 6
...                             # line 7
>>> import dis                  # line 8
>>> dis.dis(f)                  # line 9
  2           0 LOAD_GLOBAL              0 (print)
              2 LOAD_CONST               1 ('Hello')
              4 CALL_FUNCTION            1
              6 POP_TOP

  3           8 LOAD_FAST                0 (x)
             10 POP_JUMP_IF_FALSE       20

  4          12 LOAD_FAST                1 (y)
             14 LOAD_FAST                0 (x)
             16 INPLACE_ADD
             18 STORE_FAST               1 (y)

  5     >>   20 LOAD_GLOBAL              0 (print)
             22 LOAD_FAST                0 (x)
             24 LOAD_FAST                1 (y)
             26 CALL_FUNCTION            2
             28 POP_TOP

  6          30 LOAD_FAST                0 (x)
             32 LOAD_FAST                1 (y)
             34 BINARY_ADD
36 RETURN_VALUE

Bây giờ, chúng ta hãy xem mã trên. Dòng 1 đến 6 là một định nghĩa hàm. Trong dòng 8, chúng tôi nhập mô-đun 'dis' có thể được sử dụng để xem mã byte trung gian Python (hoặc bạn có thể nói, trình dịch ngược mã cho mã byte Python) được tạo bởi CPython (trình thông dịch).

LƯU Ý: Tôi đã nhận được liên kết tới mã này từ #python IRC kênh: https://Gist.github.com/nedbat/e89fa710db0edfb9057dc8d18d979f9c

Và sau đó, có Jython, được viết bằng Java và cuối cùng tạo ra mã byte Java. Mã byte Java chạy trên Môi trường chạy thi hành Java, là một triển khai của Máy ảo Java (JVM). Nếu điều này gây nhầm lẫn thì tôi nghi ngờ rằng bạn không biết Java hoạt động như thế nào. Theo thuật ngữ layman, mã Java (ngôn ngữ, không phải trình biên dịch) được trình biên dịch Java lấy và xuất ra một tệp (là mã byte Java) chỉ có thể chạy bằng JRE. Điều này được thực hiện sao cho, khi mã Java được biên dịch thì nó có thể được chuyển sang các máy khác ở định dạng mã byte Java, chỉ có thể được chạy bởi JRE. Nếu điều này vẫn còn khó hiểu thì bạn có thể muốn xem cái này trang web .

Ở đây, bạn có thể hỏi liệu mã byte của CPython có di động như Jython không, tôi nghi ngờ là không. Bytecode được tạo ra trong triển khai CPython dành riêng cho trình thông dịch đó để giúp dễ dàng thực thi mã hơn (Tôi cũng nghi ngờ rằng, việc sản xuất mã byte trung gian như vậy, chỉ để dễ dàng xử lý được thực hiện trong nhiều trình thông dịch khác). 

Vì vậy, trong Jython, khi bạn biên dịch mã Python, bạn kết thúc bằng mã byte Java, có thể chạy trên JVM.

Tương tự, IronPython (viết bằng ngôn ngữ C #) biên dịch mã Python của bạn thành Common Language Runtime (CLR), đây là một công nghệ tương tự như so với JVM, được phát triển bởi Microsoft.

Mục lục bài viết:

  • Trí nhớ là một cuốn sách trống
  • Quản lý bộ nhớ: Từ phần cứng đến phần mềm
  • Triển khai Python mặc định
  • Khóa thông dịch viên toàn cầu (GIL)
  • Thu gom rác thải
  • Quản lý bộ nhớ của CPython
    • Hồ bơi
    • Khối
    • Đấu trường
  • Phần kết luận


Bạn đã bao giờ tự hỏi làm thế nào Python xử lý dữ liệu của bạn đằng sau hậu trường? Làm thế nào các biến của bạn được lưu trữ trong bộ nhớ? Khi nào chúng bị xóa?

Trong bài viết này, chúng ta sẽ đi sâu vào bên trong của Python để hiểu cách nó xử lý việc quản lý bộ nhớ.

Đến cuối bài viết này, bạn sẽ:

  • Tìm hiểu thêm về máy tính cấp thấp, đặc biệt là liên quan đến bộ nhớ
  • Hiểu cách Python tóm tắt các hoạt động cấp thấp hơn
  • Tìm hiểu về các thuật toán quản lý bộ nhớ trong của Python

Tìm hiểu nội bộ của Python cũng sẽ cung cấp cho bạn cái nhìn sâu sắc hơn về một số hành vi của Python. Hy vọng rằng bạn cũng sẽ có được một sự đánh giá cao mới đối với Python. Rất nhiều logic đang diễn ra đằng sau hậu trường để đảm bảo chương trình của bạn hoạt động theo cách bạn mong đợi.

Trí nhớ là một cuốn sách trống

Bạn có thể bắt đầu bằng cách coi bộ nhớ của máy tính như một cuốn sách trống dành cho truyện ngắn. Chưa có gì được viết trên các trang. Cuối cùng, các tác giả khác nhau sẽ xuất hiện. Mỗi tác giả muốn một số không gian để viết câu chuyện của họ.

Vì họ không được phép viết chồng lên nhau, họ phải cẩn thận xem mình viết ở trang nào. Trước khi bắt đầu viết, họ hỏi ý kiến ​​của người quản lý cuốn sách. Sau đó, người quản lý quyết định họ được phép viết ở đâu trong cuốn sách.

Vì cuốn sách này ra đời đã lâu nên nhiều câu chuyện trong đó không còn phù hợp nữa. Khi không có ai đọc hoặc tham khảo các câu chuyện, chúng sẽ bị loại bỏ để nhường chỗ cho các câu chuyện mới.

Về bản chất, bộ nhớ máy tính giống như một cuốn sách trống đó. Trên thực tế, người ta thường gọi các khối trang bộ nhớ liền kề có độ dài cố định , vì vậy sự tương tự này khá tốt.

Các tác giả giống như các ứng dụng hoặc quy trình khác nhau cần lưu trữ dữ liệu trong bộ nhớ. Người quản lý, người quyết định nơi tác giả có thể viết trong sách, đóng vai trò là người quản lý bộ nhớ. Người dẹp bỏ những câu chuyện cũ để nhường chỗ cho những câu chuyện mới là một người thu gom rác.

Quản lý bộ nhớ: Từ phần cứng đến phần mềm

Quản lý bộ nhớ là quá trình ứng dụng đọc và ghi dữ liệu . Trình quản lý bộ nhớ xác định vị trí đặt dữ liệu của ứng dụng. Vì có một phần bộ nhớ hữu hạn, giống như các trang trong cuốn sách tương tự của chúng tôi, người quản lý phải tìm một số không gian trống và cung cấp nó cho ứng dụng. Quá trình này cung cấp bộ nhớ thường được gọi là bộ nhớ phân bổ .

Mặt khác, khi dữ liệu không còn cần thiết nữa, nó có thể bị xóa hoặc giải phóng . Nhưng giải thoát đến đâu? “Ký ức” này đến từ đâu?

Ở đâu đó trong máy tính của bạn, có một thiết bị vật lý lưu trữ dữ liệu khi bạn đang chạy các chương trình Python của mình. Tuy nhiên, có nhiều lớp trừu tượng mà mã Python phải trải qua trước khi các đối tượng thực sự truy cập vào phần cứng.

Một trong những lớp chính bên trên phần cứng (chẳng hạn như RAM hoặc ổ cứng) là hệ điều hành (OS). Nó thực hiện (hoặc từ chối) các yêu cầu đọc và ghi bộ nhớ.

Bên trên hệ điều hành, có các ứng dụng, một trong số đó là triển khai Python mặc định (được bao gồm trong hệ điều hành của bạn hoặc tải xuống từ python.org .) Việc quản lý bộ nhớ cho mã Python của bạn được ứng dụng Python xử lý. Các thuật toán và cấu trúc mà ứng dụng Python sử dụng để quản lý bộ nhớ là trọng tâm của bài viết này.

Triển khai Python mặc định

Giá trị mặc định thực hiện Python, CPython , thực sự được viết trong ngôn ngữ lập trình C .

Khi tôi lần đầu tiên nghe thấy điều này, nó đã thổi bay tâm trí của tôi. Một ngôn ngữ được viết bằng một ngôn ngữ khác ?! Chà, không hẳn, nhưng đại loại là vậy.

Ngôn ngữ Python được định nghĩa trong sổ tay tham khảo được viết bằng tiếng Anh. Tuy nhiên, bản thân sách hướng dẫn đó không phải là tất cả những gì hữu ích. Bạn vẫn cần một cái gì đó để giải thích mã đã viết dựa trên các quy tắc trong sách hướng dẫn.

Bạn cũng cần một cái gì đó để thực thi mã được thông dịch trên máy tính. Việc triển khai Python mặc định đáp ứng cả hai yêu cầu đó. Nó chuyển đổi mã Python của bạn thành các hướng dẫn để sau đó chạy trên máy ảo.

Lưu ý: Máy ảo giống như máy tính vật lý, nhưng chúng được thực hiện trong phần mềm. Chúng thường xử lý các hướng dẫn cơ bản tương tự như hướng dẫn Assembly .

Python là một ngôn ngữ lập trình thông dịch. Mã Python của bạn thực sự được biên dịch thành các hướng dẫn máy tính dễ đọc hơn được gọi là bytecode . Các hướng dẫn này được máy ảo thông dịch khi bạn chạy mã của mình.

Bạn đã bao giờ nhìn thấy một .pyctệp hoặc một __pycache__thư mục? Đó là mã bytecode được máy ảo thông dịch.

Điều quan trọng cần lưu ý là có những triển khai khác ngoài CPython. IronPython biên dịch xuống để chạy trên Thời gian chạy ngôn ngữ chung của Microsoft. Jython biên dịch thành mã bytecode của Java để chạy trên Máy ảo Java. Sau đó, có PyPy , nhưng điều đó xứng đáng với toàn bộ bài viết của riêng nó , vì vậy tôi sẽ chỉ đề cập đến nó.

Với mục đích của bài viết này, tôi sẽ tập trung vào việc quản lý bộ nhớ được thực hiện bằng cách triển khai mặc định của Python, CPython.

Tuyên bố từ chối trách nhiệm : Mặc dù rất nhiều thông tin này sẽ được chuyển sang các phiên bản Python mới, nhưng mọi thứ có thể thay đổi trong tương lai. Lưu ý rằng phiên bản được tham chiếu cho bài viết này là phiên bản Python mới nhất hiện tại , 3.7.

Được rồi, vì vậy CPython được viết bằng C và nó diễn giải mã bytecode của Python. Điều này có liên quan gì đến quản lý bộ nhớ? Vâng, các thuật toán và cấu trúc quản lý bộ nhớ tồn tại trong mã CPython, trong C. Để hiểu việc quản lý bộ nhớ của Python, bạn phải hiểu cơ bản về chính CPython.

CPython được viết bằng C, không hỗ trợ lập trình hướng đối tượng . Do đó, có khá nhiều thiết kế thú vị trong mã CPython.

Bạn có thể đã nghe nói rằng mọi thứ trong Python đều là một đối tượng, ngay cả các loại như intvà str. Chà, nó đúng ở cấp độ triển khai trong CPython. Có một cái structgọi là a PyObject, mà mọi đối tượng khác trong CPython đều sử dụng.

Lưu ý: A struct, hoặc cấu trúc , trong C là kiểu dữ liệu tùy chỉnh nhóm các kiểu dữ liệu khác nhau lại với nhau. Để so sánh với ngôn ngữ hướng đối tượng, nó giống như một lớp có thuộc tính và không có phương thức.

Ông PyObjecttổ của tất cả các đối tượng trong Python, chỉ chứa hai thứ:

  • ob_refcnt: số lượng tham chiếu
  • ob_type: con trỏ đến một loại khác

Số lượng tham chiếu được sử dụng để thu gom rác. Sau đó, bạn có một con trỏ đến kiểu đối tượng thực tế. Kiểu đối tượng đó chỉ là một kiểu khác structmô tả một đối tượng Python (chẳng hạn như a dicthoặc int).

Mỗi đối tượng có bộ cấp phát bộ nhớ dành riêng cho đối tượng của riêng nó biết cách lấy bộ nhớ để lưu đối tượng đó. Mỗi đối tượng cũng có một bộ phân bổ bộ nhớ dành riêng cho đối tượng để “giải phóng” bộ nhớ khi nó không còn cần thiết nữa.

Tuy nhiên, có một yếu tố quan trọng trong tất cả những gì nói về việc phân bổ và giải phóng bộ nhớ. Bộ nhớ là tài nguyên được chia sẻ trên máy tính và những điều tồi tệ có thể xảy ra nếu hai tiến trình khác nhau cố gắng ghi vào cùng một vị trí cùng một lúc.

Khóa thông dịch viên toàn cầu (GIL)

GIL là một giải pháp cho vấn đề chung về xử lý tài nguyên được chia sẻ, chẳng hạn như bộ nhớ trong máy tính. Khi hai luồng cố gắng sửa đổi cùng một tài nguyên cùng một lúc, chúng có thể giẫm lên nhau. Kết quả cuối cùng có thể là một mớ hỗn độn bị cắt xén mà cả hai chủ đề đều không kết thúc với những gì họ muốn.

Hãy xem xét sự tương tự cuốn sách một lần nữa. Giả sử rằng hai tác giả ngoan cố quyết định rằng đến lượt họ viết. Không chỉ vậy, cả hai đều cần phải viết trên cùng một trang của cuốn sách cùng một lúc.

Họ bỏ qua nỗ lực của người kia để tạo ra một câu chuyện và bắt đầu viết trên trang. Kết quả cuối cùng là hai câu chuyện chồng lên nhau, khiến toàn bộ trang không thể đọc được.

Một giải pháp cho vấn đề này là một khóa chung, duy nhất trên trình thông dịch khi một luồng tương tác với tài nguyên được chia sẻ (trang trong sách). Nói cách khác, chỉ một tác giả có thể viết tại một thời điểm.

GIL của Python thực hiện được điều này bằng cách khóa toàn bộ trình thông dịch, có nghĩa là không thể để một luồng khác dẫm lên luồng hiện tại. Khi CPython xử lý bộ nhớ, nó sử dụng GIL để đảm bảo rằng nó hoạt động một cách an toàn.

Có những ưu và nhược điểm đối với cách tiếp cận này và GIL được tranh luận rất nhiều trong cộng đồng Python. Để đọc thêm về GIL, tôi khuyên bạn nên xem Khóa thông dịch viên toàn cầu Python (GIL) là gì? .

Thu gom rác

Hãy xem lại sự tương tự cuốn sách và giả định rằng một số câu chuyện trong cuốn sách đang trở nên rất cũ. Không ai đang đọc hoặc tham khảo những câu chuyện đó nữa. Nếu không có ai đang đọc cái gì đó hoặc tham khảo nó trong tác phẩm của riêng họ, bạn có thể loại bỏ nó để nhường chỗ cho bài viết mới.

Văn bản cũ, không được tham chiếu đó có thể được so sánh với một đối tượng trong Python có số lượng tham chiếu đã giảm xuống 0. Hãy nhớ rằng mọi đối tượng trong Python đều có số lượng tham chiếu và con trỏ đến một kiểu.

Số lượng tham chiếu được tăng lên vì một vài lý do khác nhau. Ví dụ: số lượng tham chiếu sẽ tăng lên nếu bạn gán nó cho một biến khác:

numbers = [1, 2, 3]
# Reference count = 1
more_numbers = numbers
# Reference count = 2

Nó cũng sẽ tăng lên nếu bạn truyền đối tượng làm đối số:

Ví dụ cuối cùng, số lượng tham chiếu sẽ tăng lên nếu bạn đưa đối tượng vào danh sách:

matrix = [numbers, numbers, numbers]

Python cho phép bạn kiểm tra số lượng tham chiếu hiện tại của một đối tượng với sysmô-đun. Bạn có thể sử dụng sys.getrefcount(numbers), nhưng hãy nhớ rằng việc truyền vào đối tượng để getrefcount()tăng số lượng tham chiếu lên 1.

Trong mọi trường hợp, nếu đối tượng vẫn được yêu cầu lưu lại trong mã của bạn, thì số lượng tham chiếu của nó lớn hơn 0. Khi nó giảm xuống 0, đối tượng có một chức năng định vị cụ thể được gọi là chức năng "giải phóng" bộ nhớ để các đối tượng khác có thể sử dụng nó.

Nhưng “giải phóng” bộ nhớ có nghĩa là gì và các đối tượng khác sử dụng nó như thế nào? Hãy bắt tay ngay vào quản lý bộ nhớ của CPython.

Quản lý bộ nhớ của CPython

Chúng ta sẽ đi sâu vào kiến ​​trúc bộ nhớ và các thuật toán của CPython, vì vậy hãy thắt dây an toàn.

Như đã đề cập trước đây, có nhiều lớp trừu tượng từ phần cứng vật lý đến CPython. Hệ điều hành (OS) trừu tượng hóa bộ nhớ vật lý và tạo một lớp bộ nhớ ảo mà các ứng dụng (bao gồm cả Python) có thể truy cập.

Trình quản lý bộ nhớ ảo dành riêng cho hệ điều hành tạo ra một phần bộ nhớ cho quy trình Python. Các hộp màu xám đậm hơn trong hình ảnh bên dưới hiện thuộc sở hữu của quy trình Python.

Có nên xóa ironpython trong ổ window

Python sử dụng một phần bộ nhớ để sử dụng nội bộ và bộ nhớ không phải đối tượng. Phần khác là dành riêng cho lưu trữ đối tượng (của bạn intdictvà những thứ tương tự). Lưu ý rằng điều này đã được đơn giản hóa một chút. Nếu bạn muốn có hình ảnh đầy đủ, bạn có thể kiểm tra mã nguồn CPython , nơi tất cả việc quản lý bộ nhớ này diễn ra.

CPython có một bộ cấp phát đối tượng chịu trách nhiệm cấp phát bộ nhớ trong vùng bộ nhớ đối tượng. Bộ phân bổ đối tượng này là nơi hầu hết các điều kỳ diệu xảy ra. Nó được gọi mỗi khi một đối tượng mới cần được cấp phát hoặc xóa không gian.

Thông thường, việc thêm và xóa dữ liệu cho các đối tượng Python như listvà intkhông liên quan đến quá nhiều dữ liệu cùng một lúc. Vì vậy, thiết kế của bộ phân bổ được điều chỉnh để hoạt động tốt với lượng dữ liệu nhỏ tại một thời điểm. Nó cũng cố gắng không cấp phát bộ nhớ cho đến khi nó hoàn toàn được yêu cầu.

Các chú thích trong mã nguồn mô tả trình cấp phát là “một trình cấp phát bộ nhớ nhanh, có mục đích đặc biệt cho các khối nhỏ, được sử dụng trên đầu của một malloc có mục đích chung”. Trong trường hợp này, malloclà hàm thư viện của C để cấp phát bộ nhớ.

Bây giờ chúng ta sẽ xem xét chiến lược phân bổ bộ nhớ của CPython. Đầu tiên, chúng ta sẽ nói về 3 phần chính và cách chúng liên quan với nhau.

Các khu vực là phần lớn nhất của bộ nhớ và được căn chỉnh trên một ranh giới trang trong bộ nhớ. Ranh giới trang là cạnh của đoạn bộ nhớ liền kề có độ dài cố định mà Hệ điều hành sử dụng. Python giả định kích thước trang của hệ thống là 256 kilobyte.

Có nên xóa ironpython trong ổ window

Trong đấu trường là các nhóm, là một trang bộ nhớ ảo (4 kilobyte). Đây giống như các trang trong cuốn sách tương tự của chúng tôi. Các nhóm này được phân mảnh thành các khối bộ nhớ nhỏ hơn.

Tất cả các khối trong một nhóm nhất định đều có cùng “loại kích thước”. Một lớp kích thước xác định một kích thước khối cụ thể, với một số lượng dữ liệu được yêu cầu. Biểu đồ dưới đây được lấy trực tiếp từ các bình luận mã nguồn :

Yêu cầu theo byteKích thước của khối được phân bổKích thước lớp idx
1-8 số 8 0
9-16 16 1
17-24 24 2
25-32 32 3
33-40 40 4
41-48 48 5
49-56 56 6
57-64 64 7
65-72 72 số 8
497-504 504 62
505-512 512 63

Ví dụ: nếu 42 byte được yêu cầu, dữ liệu sẽ được đặt vào một khối kích thước 48 byte.

Hồ bơi

Hồ bơi bao gồm các khối từ một lớp kích thước duy nhất. Mỗi nhóm duy trì một danh sách liên kết kép với các nhóm khác có cùng loại kích thước. Bằng cách đó, thuật toán có thể dễ dàng tìm thấy không gian có sẵn cho một kích thước khối nhất định, thậm chí trên các nhóm khác nhau.

Một usedpoolsdanh sách theo dõi tất cả các nhóm có một số không gian có sẵn cho dữ liệu cho từng loại kích thước. Khi một kích thước khối nhất định được yêu cầu, thuật toán sẽ kiểm tra usedpoolsdanh sách này để tìm danh sách các nhóm cho kích thước khối đó.

Hồ mình phải nằm trong một trong 3 trạng thái: usedfull, hoặc empty. Một usednhóm có sẵn các khối để dữ liệu được lưu trữ. fullCác khối của một pool đều được phân bổ và chứa dữ liệu. Một emptynhóm không có dữ liệu được lưu trữ và có thể được gán bất kỳ loại kích thước nào cho các khối khi cần thiết.

Một freepoolsdanh sách theo dõi tất cả các nhóm trong emptytiểu bang. Nhưng khi nào thì các hồ trống được sử dụng?

Giả sử mã của bạn cần một đoạn bộ nhớ 8 byte. Nếu không có nhóm nào trong usedpoolslớp kích thước 8 byte, một nhóm mới emptyđược khởi tạo để lưu trữ các khối 8 byte. Nhóm mới này sau đó được thêm vào usedpoolsdanh sách để nó có thể được sử dụng cho các yêu cầu trong tương lai.

Giả sử một fullpool giải phóng một số khối của nó vì bộ nhớ không còn cần thiết nữa. Nhóm đó sẽ được thêm trở lại usedpoolsdanh sách cho loại kích thước của nó.

Bây giờ bạn có thể thấy cách các nhóm có thể di chuyển giữa các trạng thái này (và thậm chí các lớp kích thước bộ nhớ) một cách tự do với thuật toán này.

Khối

Có nên xóa ironpython trong ổ window

Như đã thấy trong sơ đồ trên, các nhóm chứa một con trỏ đến các khối bộ nhớ “miễn phí” của chúng. Có một chút sắc thái đối với cách thức hoạt động của nó. Bộ phân bổ này “cố gắng ở tất cả các cấp (đấu trường, nhóm và khối) không bao giờ chạm vào một phần bộ nhớ cho đến khi nó thực sự cần thiết,” theo các nhận xét trong mã nguồn.

Điều đó có nghĩa là một hồ bơi có thể có các khối ở 3 trạng thái. Các trạng thái này có thể được định nghĩa như sau:

  • untouched: một phần bộ nhớ chưa được cấp phát
  • free: một phần bộ nhớ đã được cấp phát nhưng sau đó được CPython cho "giải phóng" và phần đó không còn chứa dữ liệu liên quan
  • allocated: một phần bộ nhớ thực sự chứa dữ liệu có liên quan

Con freeblocktrỏ trỏ đến một danh sách các khối bộ nhớ trống được liên kết đơn lẻ. Nói cách khác, một danh sách các nơi có sẵn để đặt dữ liệu. Nếu cần nhiều hơn số khối miễn phí có sẵn, trình phân bổ sẽ nhận được một số untouchedkhối trong nhóm.

Khi trình quản lý bộ nhớ làm cho các khối "trống", các freekhối giờ đây sẽ được thêm vào phía trước freeblockdanh sách. Danh sách thực tế có thể không phải là các khối bộ nhớ liền nhau, giống như sơ đồ đẹp đầu tiên. Nó có thể trông giống như sơ đồ bên dưới:

Có nên xóa ironpython trong ổ window

Đấu trường

Các khu vực chứa hồ bơi. Những hồ bơi có thể usedfullhoặc empty. Bản thân các đấu trường không có trạng thái rõ ràng như các hồ bơi.

Thay vào đó, các khu vực được tổ chức thành một danh sách liên kết kép được gọi là usable_arenas. Danh sách được sắp xếp theo số lượng hồ bơi miễn phí có sẵn. Càng ít hồ bơi miễn phí, đấu trường càng gần phía trước danh sách.

Có nên xóa ironpython trong ổ window

Điều này có nghĩa là đấu trường có đầy đủ dữ liệu nhất sẽ được chọn để đặt dữ liệu mới vào. Nhưng tại sao không phải là ngược lại? Tại sao không đặt dữ liệu ở nơi có nhiều dung lượng nhất?

Điều này đưa chúng ta đến ý tưởng giải phóng bộ nhớ thực sự. Bạn sẽ nhận thấy rằng tôi đã nói "miễn phí" trong dấu ngoặc kép khá nhiều. Lý do là khi một khối được coi là "trống", bộ nhớ đó không thực sự được giải phóng trở lại hệ điều hành. Quy trình Python giữ nó được phân bổ và sẽ sử dụng nó sau này cho dữ liệu mới. Thực sự giải phóng bộ nhớ sẽ trả nó trở lại hệ điều hành để sử dụng.

Đấu trường là những thứ duy nhất có thể thực sự được giải phóng. Vì vậy, đó là lý do mà những đấu trường gần hơn trống rỗng nên được phép trở nên trống rỗng. Bằng cách đó, phần bộ nhớ đó có thể được giải phóng thực sự, giảm dung lượng bộ nhớ tổng thể của chương trình Python của bạn.

Phần kết luận

Quản lý bộ nhớ là một phần không thể thiếu khi làm việc với máy tính. Python xử lý gần như tất cả mọi thứ đằng sau hậu trường, tốt hơn hoặc xấu hơn.

Trong bài viết này, bạn đã học được:

  • Quản lý bộ nhớ là gì và tại sao nó lại quan trọng
  • Cách triển khai Python mặc định, CPython, được viết bằng ngôn ngữ lập trình C.
  • Cách cấu trúc dữ liệu và thuật toán hoạt động cùng nhau trong quản lý bộ nhớ của CPython để xử lý dữ liệu của bạn

Python loại bỏ rất nhiều chi tiết phức tạp khi làm việc với máy tính. Điều này mang lại cho bạn sức mạnh để làm việc ở cấp độ cao hơn để phát triển mã của bạn mà không phải đau đầu lo lắng về cách thức và nơi lưu trữ tất cả các byte đó.