Hướng dẫn can python access memory directly? - python có thể truy cập bộ nhớ trực tiếp không?

41

Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.
Learn more.

Câu hỏi của tôi là: Làm thế nào tôi có thể đọc nội dung của một địa chỉ bộ nhớ trong Python? Ví dụ: ptr = id (7) Tôi muốn đọc nội dung của bộ nhớ được trỏ bởi PTR. Cảm ơn.

Hướng dẫn can python access memory directly? - python có thể truy cập bộ nhớ trực tiếp không?

Mark Tolonen

156K24 Huy hiệu vàng163 Huy hiệu bạc237 Huy hiệu Đồng24 gold badges163 silver badges237 bronze badges

Đã hỏi ngày 23 tháng 11 năm 2011 lúc 23:42Nov 23, 2011 at 23:42

Hướng dẫn can python access memory directly? - python có thể truy cập bộ nhớ trực tiếp không?

3

Có một cái nhìn vào ctypes.string_at. Đây là một ví dụ. Nó bỏ cấu trúc dữ liệu thô của số nguyên Cpython.

from ctypes import string_at
from sys import getsizeof

a = 0x7fff 
print(string_at(id(a),getsizeof(a)).hex())

Output:

0200000000000000d00fbeaafe7f00000100000000000000ff7f0000

Lưu ý rằng điều này hoạt động với việc triển khai CPython vì id() xảy ra để trả về địa chỉ bộ nhớ ảo của đối tượng Python, nhưng điều này không được bảo đảm bởi chính ngôn ngữ Python.

Đã trả lời ngày 24 tháng 11 năm 2011 lúc 0:22Nov 24, 2011 at 0:22

Hướng dẫn can python access memory directly? - python có thể truy cập bộ nhớ trực tiếp không?

Mark Tolonenmark TolonenMark Tolonen

156K24 Huy hiệu vàng163 Huy hiệu bạc237 Huy hiệu Đồng24 gold badges163 silver badges237 bronze badges

0

Đã hỏi ngày 23 tháng 11 năm 2011 lúc 23:42

Có một cái nhìn vào ctypes.string_at. Đây là một ví dụ. Nó bỏ cấu trúc dữ liệu thô của số nguyên Cpython.Nov 24, 2011 at 0:10

Lưu ý rằng điều này hoạt động với việc triển khai CPython vì id() xảy ra để trả về địa chỉ bộ nhớ ảo của đối tượng Python, nhưng điều này không được bảo đảm bởi chính ngôn ngữ Python.Raymond Hettinger

Đã trả lời ngày 24 tháng 11 năm 2011 lúc 0:2262 gold badges367 silver badges469 bronze badges

Mark Tolonenmark Tolonen

Trong Python, bạn thường không sử dụng con trỏ để truy cập bộ nhớ trừ khi bạn giao tiếp với ứng dụng C. Nếu đó là những gì bạn cần, hãy xem mô -đun CTYPES cho các chức năng của người truy cập.

Đã trả lời ngày 24 tháng 11 năm 2011 lúc 0:10Nov 24, 2011 at 1:49

Raymond Hettingerraymond HettingerBen

208K62 Huy hiệu vàng367 Huy hiệu bạc469 Huy hiệu Đồng20 gold badges125 silver badges169 bronze badges

1

Bạn đang cố gắng "đảo ngược" id để lấy đối tượng Python thing từ kết quả của id(thing)? Tôi thậm chí không biết nếu điều đó có thể được thực hiện, và nó chắc chắn không nên được thực hiện; Nó sẽ đánh bại bộ sưu tập rác và dẫn đến việc thiếu an toàn bộ nhớ. Nếu chương trình của bạn thực hiện điều đó có nghĩa là bạn có hiệu quả có tài liệu tham khảo về mọi thứ (số id) mà người thu gom rác không biết là tài liệu tham khảo, vì vậy nó có thể phát hành các đối tượng bạn vẫn đang sử dụng (tùy thuộc vào những gì xảy ra trong phần còn lại của chương trình ).

Nếu bạn đang cố đọc bộ nhớ thô từ một con trỏ mà bạn đã được trả về từ phần mở rộng C hoặc một cái gì đó, thì các câu trả lời khác có thể giúp bạn.

Đã trả lời ngày 24 tháng 11 năm 2011 lúc 1:4921 gold badges182 silver badges185 bronze badges

BenbenJan 1, 2020 at 19:48

64,9K20 Huy hiệu vàng125 Huy hiệu bạc169 Huy hiệu đồngDev Rishi Khare

Nếu bạn đang cố gắng truy cập các tệp nhị phân lớn như hình ảnh và video và không nhất thiết cần chúng trong bộ nhớ mãi mãi, hãy xem xét sử dụng yếu.1 gold badge3 silver badges8 bronze badges

Xem bây giờ hướng dẫn này có một khóa học video liên quan được tạo bởi nhóm Python thực sự. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn về sự hiểu biết của bạn: Làm thế nào Python quản lý bộ nhớ This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: How Python Manages Memory

Làm thế nào để Python truy cập bộ nhớ?

Quản lý bộ nhớ trong Python liên quan đến một đống riêng tư chứa tất cả các đối tượng Python và cấu trúc dữ liệu. Việc quản lý đống riêng tư này được đảm bảo trong nội bộ bởi Trình quản lý bộ nhớ Python.

Python có thể viết vào bộ nhớ không?

  • Viết một tệp ánh xạ bộ nhớ bằng MMAP của Python. Ánh xạ bộ nhớ là hữu ích nhất để đọc các tệp, nhưng bạn cũng có thể sử dụng nó để ghi các tệp. API MMAP để viết các tệp rất giống với I/O tệp thông thường ngoại trừ một vài khác biệt.
  • Làm thế nào để Python lưu trữ dữ liệu trong bộ nhớ?
  • Có thể lưu trữ trạng thái của một đối tượng Python dưới dạng luồng byte trực tiếp vào một tệp hoặc luồng bộ nhớ và truy xuất trạng thái ban đầu của nó. Quá trình này được gọi là tuần tự hóa và khử serialization. Thư viện được xây dựng của Python chứa các mô -đun khác nhau cho quá trình tuần tự hóa và giải phóng hóa.

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 sự đánh giá cao mới cho Python. Rất nhiều logic đang xảy 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.

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

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

Vì họ không được phép viết thư cho nhau, họ phải cẩn thận về những trang họ viết. Trước khi họ bắt đầu viết, họ tham khảo ý kiến ​​người quản lý của cuốn sách. Người quản lý sau đó quyết định nơi nào trong cuốn sách mà họ cho phép viết.

Vì cuốn sách này là khoảng thời gian dài, nhiều câu chuyện trong đó không còn liên quan. Khi không ai đọc hoặc tham khảo các câu chuyện, họ sẽ được gỡ bỏ để nhường chỗ cho những câu chuyện mới.

Về bản chất, bộ nhớ máy tính giống như cuốn sách trống. Trên thực tế, nó phổ biến để gọi các khối bộ nhớ có độ dài có độ dài cố định, do đó, sự tương tự này được giữ khá tốt.pages, so this analogy holds pretty well.

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 các tác giả có thể viết trong cuốn sách, đóng vai trò là người quản lý bộ nhớ của các loại. Người đã loại bỏ những câu chuyện cũ để nhường chỗ cho những người 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 mà các ứng dụng đọc và ghi dữ liệu. Trình quản lý bộ nhớ xác định nơi đặt dữ liệu ứng dụng. Vì có một đoạ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 cung cấp bộ nhớ này thường được gọi là phân bổ bộ nhớ.allocation.

Mặt khác, khi dữ liệu không còn cần thiết, nó có thể bị xóa hoặc được giải phóng. Nhưng được giải phóng đến đâu? Bộ nhớ này đến từ đâu?freed. But freed to where? Where did this “memory” come from?

Ở đâ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. Có nhiều lớp trừu tượng mà mã Python đi qua trước khi các đối tượng thực sự đi đến phần cứng.

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

Trên HĐH, có các ứng dụng, một trong số đó là triển khai Python mặc định (bao gồm trong HĐH của bạn hoặc được tải xuống từ Python.org.) Quản lý bộ nhớ cho mã Python của bạn được xử lý bởi ứng dụng Python. 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.

Việc triển khai Python mặc định

Việc triển khai Python mặc định, CPython, thực sự được viết bằng 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 vào tâm trí tôi. Một ngôn ngữ mà viết bằng ngôn ngữ khác ?! Vâng, không thực sự, nhưng loại.

Ngôn ngữ Python được định nghĩa trong một hướng dẫn tham khảo được viết bằng tiếng Anh. Tuy nhiên, 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ã bằng văn bản dựa trên các quy tắc trong hướng dẫn.

Bạn cũng cần một cái gì đó để thực sự thực hiện mã được giải thí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 đó nó chạy trên một máy ảo.

Python là một ngôn ngữ lập trình được giải thích. Mã Python của bạn thực sự được biên dịch cho các hướng dẫn có thể đọc được nhiều hơn được gọi là mã byte. Các hướng dẫn này được giải thích bằng một máy ảo khi bạn chạy mã của mình.interpreted by a virtual machine when you run your code.

Bạn đã bao giờ xem một tệp .pyc hoặc thư mục

0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
0 chưa? Đó là mã byte được giải thích bằng máy ảo.

Đ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 xuống mã byte 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 mình, vì vậy tôi sẽ chỉ đề cập đến nó.

Đối với các 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.

Được rồi, vì vậy CPython được viết bằng C và nó diễn giải mã Python byte. Điều này có liên quan gì đến quản lý bộ nhớ? Chà, 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 đượ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 là một đối tượng, thậm chí các loại như

0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
1 và
0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
2. Chà, nó đúng ở cấp độ triển khai trong CPython. Có một
0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
3 được gọi là
0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
4, mà mọi đối tượng khác trong Cpython đều sử dụng.

0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
4, người đàn ông lớn của tất cả các đối tượng trong Python, chỉ chứa hai điều:

  • 0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
    
    6: Số lượng tham chiếu
    reference count
  • 0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
    
    7: Con trỏ sang loại khác
    pointer to another type

Số lượng tham chiếu được sử dụng để thu gom rác. Sau đó, bạn có một con trỏ đến loại đối tượng thực tế. Loại đối tượng đó chỉ là một

0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
3 khác mô tả một đối tượng Python (chẳng hạn như
0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
9 hoặc
0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
1).

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

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à một tài nguyên được chia sẻ trên máy tính và những điều xấu có thể xảy ra nếu hai quy 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 phiên dịch toàn cầu (Gil)

GIL là một giải pháp cho vấn đề chung là xử lý các tài nguyên được chia sẻ, 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ể bước lên các ngón chân của nhau. Kết quả cuối cùng có thể là một mớ hỗn độn mà cả hai chủ đề không kết thúc với những gì họ muốn.

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

Họ từng bỏ qua những nỗ lực khác của người khác để 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 trên nhau, điều này làm cho toàn bộ trang hoàn toàn không thể đọc được.

Một giải pháp cho vấn đề này là một khóa toàn cầu 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 cuốn sách). Nói cách khác, chỉ có một tác giả có thể viết cùng một lúc.

Python sườn Gil hoàn thành điều này bằng cách khóa toàn bộ trình thông dịch, có nghĩa là nó không thể cho một chủ đề khác bước lên tên 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 phương pháp 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 kiểm tra khóa phiên dịch viên toàn cầu Python là gì ?.

Thu gom rác thải

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

Bài viết cũ, không được giới thiệ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 còn

numbers = [1, 2, 3]
# Reference count = 1
more_numbers = numbers
# Reference count = 2
1. Hãy nhớ rằng mọi đối tượng trong Python đều có số lượng tham chiếu và một con trỏ đến một loại.

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 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 nếu bạn vượt qua đối tượng như một đối số:

Ví dụ cuối cùng, số lượng tham chiếu sẽ tăng 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 mô -đun

numbers = [1, 2, 3]
# Reference count = 1
more_numbers = numbers
# Reference count = 2
2. Bạn có thể sử dụng
numbers = [1, 2, 3]
# Reference count = 1
more_numbers = numbers
# Reference count = 2
3, nhưng hãy nhớ rằng việc truyền trong đối tượng cho
numbers = [1, 2, 3]
# Reference count = 1
more_numbers = numbers
# Reference count = 2
4 tăng số lượng tham chiếu bằng
numbers = [1, 2, 3]
# Reference count = 1
more_numbers = numbers
# Reference count = 2
5.

Trong mọi trường hợp, nếu đối tượng vẫn được yêu cầu treo xung quanh mã của bạn, số lượng tham chiếu của nó lớn hơn

numbers = [1, 2, 3]
# Reference count = 1
more_numbers = numbers
# Reference count = 2
1. Khi nó rơi xuống
numbers = [1, 2, 3]
# Reference count = 1
more_numbers = numbers
# Reference count = 2
1, đối tượng có một chức năng giải quyết cụ thể được gọi là mà giải phóng bộ nhớ để các đối tượng khác có thể sử dụng nó.

Nhưng nó có ý nghĩa gì với bộ nhớ miễn phí, và làm thế nào để các đối tượng khác sử dụng nó? Hãy cùng nhảy ngay vào quản lý bộ nhớ CPython.

Quản lý bộ nhớ CPython sườn

Chúng tôi sẽ đi sâu vào kiến ​​trúc và thuật toán bộ nhớ của Cpython, vì vậy hãy khóa lại.

Như đã đề cập trước đây, có các lớp trừu tượng từ phần cứng vật lý đến cpython. Hệ điều hành (HĐH) 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.

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

Hướng dẫn can python access memory directly? - python có thể truy cập bộ nhớ trực tiếp không?

Python sử dụng một phần của bộ nhớ để sử dụng nội bộ và bộ nhớ không đối tượng. Phần khác được dành riêng cho lưu trữ đối tượng (

0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
1 của bạn,
0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
9 và tương tự). Lưu ý rằng điều này có phần đơn giản hóa. Nếu bạn muốn hình ảnh đầy đủ, bạn có thể kiểm tra mã nguồn Cpython, nơi tất cả các quản lý bộ nhớ này xảy ra.

CPYThon có một trình phân bổ đối tượng chịu trách nhiệm phân bổ bộ nhớ trong vùng bộ nhớ đối tượng. Phân bổ đối tượng này là nơi hầu hết các phép thuật xảy ra. Nó được gọi mỗi khi một đối tượng mới cần không gian được phân bổ hoặc xóa.

Thông thường, việc thêm và xóa dữ liệu cho các đối tượng Python như

matrix = [numbers, numbers, numbers]
0 và
0200000000000000d00fbeaafe7f00000100000000000000ff7f0000
1 không liên quan đến quá nhiều dữ liệu tại một thời điểm. Vì vậy, thiết kế của bộ phân bổ được điều chỉnh để hoạt động tốt với một lượng nhỏ dữ liệu cùng một lúc. Nó cũng cố gắng không phân bổ bộ nhớ cho đến khi nó hoàn toàn yêu cầu.

Các nhận xét trong mã nguồn mô tả bộ phân bổ là bộ phân bổ bộ nhớ có mục đích nhanh, nhanh cho các khối nhỏ, được sử dụng trên đỉnh của một malloc đa năng. Trong trường hợp này,

matrix = [numbers, numbers, numbers]
2 là chức năng thư viện CTHER để phân bổ bộ nhớ.

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

Đấu trường là những khối bộ nhớ lớn nhất và được căn chỉnh trên một ranh giới trang trong bộ nhớ. Một ranh giới trang là cạnh của một đoạn bộ nhớ liên tục có độ dài cố định mà HĐH sử dụng. Python giả định kích thước trang của hệ thống là 256 kilobyte.

Hướng dẫn can python access memory directly? - python có thể truy cập bộ nhớ trực tiếp không?

Trong các đấu trường là các hồ bơi, 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 một lớp kích thước. Một lớp kích thước xác định 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 nhận xét mã nguồn:

Yêu cầu trong byteKích thước của khối được phân bổKích thước lớp IDX
1-88 0
9-1616 1
17-2424 2
25-3232 3
33-4040 4
41-4848 5
49-5656 6
57-6464 7
65-7272 8
497-504504 62
505-512512 63

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

Hồ bơi

Các nhóm 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 đến các nhóm khác có cùng lớp. Theo 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.

Danh sách

matrix = [numbers, numbers, numbers]
3 theo dõi tất cả các nhóm có sẵn một số không gian cho dữ liệu cho từng lớp 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 danh sách
matrix = [numbers, numbers, numbers]
3 này cho danh sách các nhóm cho kích thước khối đó.

Bản thân các nhóm phải ở một trong 3 tiểu bang:

matrix = [numbers, numbers, numbers]
5,
matrix = [numbers, numbers, numbers]
6 hoặc
matrix = [numbers, numbers, numbers]
7. Một nhóm
matrix = [numbers, numbers, numbers]
5 có các khối có sẵn cho dữ liệu được lưu trữ. Một khối nhóm
matrix = [numbers, numbers, numbers]
6 đều được phân bổ và chứa dữ liệu. Một nhóm
matrix = [numbers, numbers, numbers]
7 không có dữ liệu được lưu trữ và có thể được chỉ định bất kỳ lớp kích thước nào cho các khối khi cần thiết.

Danh sách id()1 theo dõi tất cả các nhóm ở trạng thái

matrix = [numbers, numbers, numbers]
7. Nhưng khi nào các bể 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ó hồ bơi trong

matrix = [numbers, numbers, numbers]
3 của lớp kích thước 8 byte, một nhóm
matrix = [numbers, numbers, numbers]
7 mới đượ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 danh sách
matrix = [numbers, numbers, numbers]
3 để nó có thể được sử dụng cho các yêu cầu trong tương lai.

Nói một hồ bơi

matrix = [numbers, numbers, numbers]
6 giải phóng một số khối của nó vì bộ nhớ không còn cần thiết. Nhóm đó sẽ được thêm vào danh sách
matrix = [numbers, numbers, numbers]
3 cho lớp 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

Hướng dẫn can python access memory directly? - python có thể truy cập bộ nhớ trực tiếp không?

Như đã thấy trong sơ đồ trên, các nhóm chứa một con trỏ tới các khối bộ nhớ miễn phí của họ. Có một sắc thái nhỏ cho cách thức hoạt động của nó. Phân bổ này, người khác phấn đấu ở 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 bình luận trong mã nguồn.

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

  • id()8: Một phần bộ nhớ chưa được phân bổ a portion of memory that has not been allocated
  • id()9: Một phần bộ nhớ được phân bổ nhưng sau đó đã tạo ra miễn phí bởi CPYthon và không còn chứa dữ liệu liên quan a portion of memory that was allocated but later made “free” by CPython and that no longer contains relevant data
  • id0: Một phần bộ nhớ thực sự chứa dữ liệu liên quan a portion of memory that actually contains relevant data

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

Khi trình quản lý bộ nhớ tạo các khối miễn phí, thì bây giờ các khối id()9 được thêm vào mặt trước của danh sách id1. Danh sách thực tế có thể không phải là khối bộ nhớ tiếp giáp, như sơ đồ đẹp đầu tiên. Nó có thể trông giống như sơ đồ dưới đây:

Hướng dẫn can python access memory directly? - python có thể truy cập bộ nhớ trực tiếp không?

Đấu trường

Đấu trường chứa hồ bơi. Những hồ bơi đó có thể là

matrix = [numbers, numbers, numbers]
5,
matrix = [numbers, numbers, numbers]
6 hoặc
matrix = [numbers, numbers, numbers]
7. Bản thân các đấu trường don don có trạng thái rõ ràng như hồ bơi.

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

Hướng dẫn can python access memory directly? - python có thể truy cập bộ nhớ trực tiếp không?

Điều này có nghĩa là đấu trường đầ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 ngược lại? Tại sao không đặt dữ liệu ở nơi có không gian có sẵn nhất?

Điều này đưa chúng ta đến ý tưởng thực sự giải phóng trí nhớ. Bạn có thể nhận thấy rằng tôi đã nói rằng miễn phí trong các trích dẫn khá nhiều. Lý do là khi một khối được coi là miễn phí, bộ nhớ đó không thực sự được giải phóng trở lại hệ điều hành. Quá trình Python giữ cho 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ớ trả lại cho hệ điều hành để sử dụng.

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

Sự kết luận

Quản lý bộ nhớ là một phần không thể thiếu trong việc làm việc với máy tính. Python xử lý gần như tất cả những thứ đằng sau hậu trường, tốt hơn hoặc tồi tệ 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 thực hiện Python mặc định, CPython, được viết bằng ngôn ngữ lập trình C.
  • Cách các cấu trúc dữ liệu và thuật toán hoạt động cùng nhau trong quản lý bộ nhớ CPython, để xử lý dữ liệu của bạn

Python tóm tắt rất nhiều chi tiết nghiệt ngã khi làm việc với máy tính. Điều này cung cấp 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 về việc lo lắng về cách thức và nơi tất cả các byte đó được lưu trữ.

Xem bây giờ hướng dẫn này có một khóa học video liên quan được tạo bởi nhóm Python thực sự. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn về sự hiểu biết của bạn: Làm thế nào Python quản lý bộ nhớ This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: How Python Manages Memory

Làm thế nào để Python truy cập bộ nhớ?

Quản lý bộ nhớ trong Python liên quan đến một đống riêng tư chứa tất cả các đối tượng Python và cấu trúc dữ liệu. Việc quản lý đống riêng tư này được đảm bảo trong nội bộ bởi Trình quản lý bộ nhớ Python.internally by the Python memory manager.

Python có thể viết vào bộ nhớ không?

Viết một tệp ánh xạ bộ nhớ bằng MMAP của Python. Ánh xạ bộ nhớ là hữu ích nhất để đọc các tệp, nhưng bạn cũng có thể sử dụng nó để ghi các tệp. API MMAP để viết các tệp rất giống với I/O tệp thông thường ngoại trừ một vài khác biệt.you can also use it to write files. The mmap API for writing files is very similar to regular file I/O except for a few differences.

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

Có thể lưu trữ trạng thái của một đối tượng Python dưới dạng luồng byte trực tiếp vào một tệp hoặc luồng bộ nhớ và truy xuất trạng thái ban đầu của nó.Quá trình này được gọi là tuần tự hóa và khử serialization.Thư viện được xây dựng của Python chứa các mô -đun khác nhau cho quá trình tuần tự hóa và giải phóng hóa.byte stream directly to a file, or memory stream and retrieve to its original state. This process is called serialization and de-serialization. Python's built in library contains various modules for serialization and deserialization process.

Python có phát hành bộ nhớ không?

Không giống như nhiều ngôn ngữ khác, Python không nhất thiết phải phát hành bộ nhớ trở lại hệ điều hành.Thay vào đó, nó có một bộ phân bổ đối tượng chuyên dụng cho các đối tượng nhỏ hơn 512 byte, giữ một số khối bộ nhớ đã được phân bổ để sử dụng tiếp theo trong tương lai.Python does not necessarily release the memory back to the Operating System. Instead, it has a dedicated object allocator for objects smaller than 512 bytes, which keeps some chunks of already allocated memory for further use in the future.