Quản lý bộ nhớ trong Python liên quan đến một đống riêng chứa tất cả các đối tượng Python và cấu trúc dữ liệu. Việc quản lý vùng riêng tư này được đảm bảo nội bộ bởi trình quản lý bộ nhớ Python. Trình quản lý bộ nhớ Python có các thành phần khác nhau xử lý các khía cạnh quản lý lưu trữ động khác nhau, như chia sẻ, phân đoạn, phân bổ trước hoặc bộ nhớ đệm
Ở mức thấp nhất, bộ cấp phát bộ nhớ thô đảm bảo rằng có đủ chỗ trong vùng riêng tư để lưu trữ tất cả dữ liệu liên quan đến Python bằng cách tương tác với trình quản lý bộ nhớ của hệ điều hành. Ngoài bộ cấp phát bộ nhớ thô, một số bộ cấp phát dành riêng cho đối tượng hoạt động trên cùng một vùng nhớ và thực hiện các chính sách quản lý bộ nhớ riêng biệt phù hợp với đặc thù của từng loại đối tượng. Ví dụ: các đối tượng số nguyên được quản lý khác nhau trong heap so với chuỗi, bộ dữ liệu hoặc từ điển vì số nguyên bao hàm các yêu cầu lưu trữ khác nhau và sự đánh đổi giữa tốc độ/không gian. Do đó, trình quản lý bộ nhớ Python ủy thác một số công việc cho bộ cấp phát dành riêng cho đối tượng, nhưng đảm bảo rằng bộ cấp phát sau hoạt động trong giới hạn của vùng riêng tư
Điều quan trọng là phải hiểu rằng việc quản lý heap Python được thực hiện bởi chính trình thông dịch và người dùng không có quyền kiểm soát nó, ngay cả khi họ thường xuyên thao tác các con trỏ đối tượng tới các khối bộ nhớ bên trong heap đó. Việc phân bổ không gian heap cho các đối tượng Python và các bộ đệm bên trong khác được trình quản lý bộ nhớ Python thực hiện theo yêu cầu thông qua các hàm API Python/C được liệt kê trong tài liệu này
Để tránh hỏng bộ nhớ, người viết tiện ích mở rộng không bao giờ được thử thao tác trên các đối tượng Python bằng các hàm do thư viện C xuất ra. malloc[]
, calloc[]
, realloc[]
và free[]
. Điều này sẽ dẫn đến các cuộc gọi hỗn hợp giữa trình cấp phát C và trình quản lý bộ nhớ Python với hậu quả nghiêm trọng, bởi vì chúng triển khai các thuật toán khác nhau và hoạt động trên các vùng khác nhau. Tuy nhiên, người ta có thể cấp phát và giải phóng các khối bộ nhớ một cách an toàn bằng bộ cấp phát thư viện C cho các mục đích riêng lẻ, như minh họa trong ví dụ sau
PyObject *res; char *buf = [char *] malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; ...Do some I/O operation involving buf... res = PyBytes_FromString[buf]; free[buf]; /* malloc'ed */ return res;
Trong ví dụ này, yêu cầu bộ nhớ cho bộ đệm I/O được xử lý bởi bộ cấp phát thư viện C. Kết quả là trình quản lý bộ nhớ Python chỉ liên quan đến việc phân bổ đối tượng byte được trả về
Tuy nhiên, trong hầu hết các trường hợp, nên phân bổ bộ nhớ cụ thể từ heap Python vì heap nằm dưới sự kiểm soát của trình quản lý bộ nhớ Python. Ví dụ: điều này là bắt buộc khi trình thông dịch được mở rộng với các loại đối tượng mới được viết bằng C. Một lý do khác để sử dụng heap Python là mong muốn thông báo cho trình quản lý bộ nhớ Python về nhu cầu bộ nhớ của mô-đun mở rộng. Ngay cả khi bộ nhớ được yêu cầu được sử dụng riêng cho các mục đích nội bộ, có tính đặc biệt cao, việc ủy quyền tất cả các yêu cầu bộ nhớ cho trình quản lý bộ nhớ Python sẽ khiến trình thông dịch có hình ảnh chính xác hơn về toàn bộ dung lượng bộ nhớ của nó. Do đó, trong một số trường hợp nhất định, trình quản lý bộ nhớ Python có thể kích hoạt hoặc không kích hoạt các hành động thích hợp, như thu gom rác, nén bộ nhớ hoặc các quy trình phòng ngừa khác. Lưu ý rằng bằng cách sử dụng bộ cấp phát thư viện C như trong ví dụ trước, bộ nhớ được cấp phát cho bộ đệm I/O thoát hoàn toàn khỏi trình quản lý bộ nhớ Python
Xem thêm
Biến môi trường có thể được sử dụng để định cấu hình bộ cấp phát bộ nhớ được sử dụng bởi Python
Biến môi trường có thể được sử dụng để in số liệu thống kê mỗi khi một đấu trường đối tượng pymalloc mới được tạo và khi tắt máy
Tên miền cấp phát
Tất cả các chức năng phân bổ thuộc về một trong ba “miền” khác nhau [xem thêm]. Các miền này đại diện cho các chiến lược phân bổ khác nhau và được tối ưu hóa cho các mục đích khác nhau. Chi tiết cụ thể về cách mọi miền phân bổ bộ nhớ hoặc chức năng nội bộ mà mỗi miền gọi được coi là chi tiết triển khai, nhưng để gỡ lỗi, bạn có thể tìm thấy bảng đơn giản hóa tại. Không có yêu cầu khó sử dụng bộ nhớ được trả về bởi các hàm cấp phát thuộc về một miền nhất định chỉ cho các mục đích được gợi ý bởi miền đó [mặc dù đây là phương pháp được khuyến nghị]. Ví dụ: người ta có thể sử dụng bộ nhớ được trả về để phân bổ các đối tượng Python hoặc bộ nhớ được trả về để phân bổ bộ nhớ cho bộ đệm
Ba miền phân bổ là
tên miền thô. dành cho việc cấp phát bộ nhớ cho các bộ đệm bộ nhớ có mục đích chung trong đó việc cấp phát phải đến bộ cấp phát hệ thống hoặc nơi cấp phát có thể hoạt động mà không cần. Bộ nhớ được yêu cầu trực tiếp đến hệ thống
Miền “Mem”. dành cho việc phân bổ bộ nhớ cho bộ đệm Python và bộ đệm bộ nhớ đa năng trong đó việc phân bổ phải được thực hiện với bộ đệm được giữ. Bộ nhớ được lấy từ đống riêng của Python
miền đối tượng. dành cho việc phân bổ bộ nhớ thuộc về các đối tượng Python. Bộ nhớ được lấy từ đống riêng của Python
Khi giải phóng bộ nhớ được cấp phát trước đó bởi các chức năng cấp phát thuộc một miền nhất định, phải sử dụng các chức năng cấp phát cụ thể phù hợp. Ví dụ: phải được sử dụng để giải phóng bộ nhớ được cấp phát bằng cách sử dụng
Giao diện bộ nhớ thô
Các bộ chức năng sau đây là các trình bao bọc cho bộ cấp phát hệ thống. Các chức năng này an toàn cho luồng, không cần phải giữ
Việc sử dụng các chức năng sau. malloc[]
, calloc[]
, realloc[]
và free[]
;
Mới trong phiên bản 3. 4
void *PyMem_RawMalloc[size_t n]Cấp phát n byte và trả về một con trỏ loại void* cho bộ nhớ được cấp phát hoặc
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1 .
Yêu cầu các byte bằng 0 trả về một con trỏ khác biệt không phải ____2_______1 nếu có thể, như thể thay vào đó
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;3 đã được gọi. Bộ nhớ sẽ không được khởi tạo theo bất kỳ cách nàovoid *PyMem_RawCalloc[size_t nelem, size_t elsize]
Cấp phát các phần tử nelem, mỗi phần tử có kích thước theo byte là elsize và trả về một con trỏ loại void* . Bộ nhớ được khởi tạo bằng không.
Yêu cầu các phần tử bằng 0 hoặc các phần tử có kích thước byte bằng 0 trả về một con trỏ không phải ______2_______1 riêng biệt nếu có thể, như thể thay vào đó,
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;6 đã được gọi
Mới trong phiên bản 3. 5
void *PyMem_RawRealloc[void *p, size_t n]Thay đổi kích thước khối bộ nhớ được trỏ tới bởi p thành n byte. Nội dung sẽ không thay đổi ở mức tối thiểu của kích thước cũ và mới
Nếu p là
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1, cuộc gọi tương đương với
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;8;
Trừ khi p là
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1, nó phải được trả về bởi một lệnh gọi trước đó tới , hoặc
Nếu yêu cầu không thành công, trả về
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1 và p vẫn là một con trỏ hợp lệ tới vùng bộ nhớ trước đóvoid PyMem_RawFree[void *p]
Giải phóng khối bộ nhớ được trỏ tới bởi p, khối này phải được trả về bởi lệnh gọi trước đó tới , hoặc. Mặt khác, hoặc nếu
char *buf1 = PyMem_New[char, BUFSIZ]; char *buf2 = [char *] malloc[BUFSIZ]; char *buf3 = [char *] PyMem_Malloc[BUFSIZ]; ... PyMem_Del[buf3]; /* Wrong -- should be PyMem_Free[] */ free[buf2]; /* Right -- allocated via malloc[] */ free[buf1]; /* Fatal -- should be PyMem_Del[] */9 đã được gọi trước đó, hành vi không xác định sẽ xảy ra
Nếu p là
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1, không có thao tác nào được thực hiện
Giao diện bộ nhớ
Các bộ chức năng sau đây, được lập mô hình theo tiêu chuẩn ANSI C, nhưng chỉ định hành vi khi yêu cầu byte bằng 0, có sẵn để cấp phát và giải phóng bộ nhớ khỏi heap Python
Việc sử dụng
Cảnh báo
Phải được tổ chức khi sử dụng các chức năng này
Đã thay đổi trong phiên bản 3. 6. Bộ cấp phát mặc định hiện là pymalloc thay vì hệ thống malloc[]
.
một phần của
Cấp phát n byte và trả về một con trỏ loại void* cho bộ nhớ được cấp phát hoặc
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1 .
Yêu cầu các byte bằng 0 trả về một con trỏ không phải ____2_______1 nếu có thể, như thể thay vào đó, malloc[]
4 đã được gọi. Bộ nhớ sẽ không được khởi tạo theo bất kỳ cách nào
Một phần của kể từ phiên bản 3. 7
Cấp phát các phần tử nelem, mỗi phần tử có kích thước theo byte là elsize và trả về một con trỏ loại void* . Bộ nhớ được khởi tạo bằng không.
Yêu cầu các phần tử bằng 0 hoặc các phần tử có kích thước byte bằng 0 trả về một con trỏ không phải ______2_______1 riêng biệt nếu có thể, như thể thay vào đó, malloc[]
7 đã được gọi
Mới trong phiên bản 3. 5
void *PyMem_Realloc[void *p, size_t n]một phần của
Thay đổi kích thước khối bộ nhớ được trỏ tới bởi p thành n byte. Nội dung sẽ không thay đổi ở mức tối thiểu của kích thước cũ và mới
Nếu p là
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1, cuộc gọi tương đương với
malloc[]
9; Trừ khi p là
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1, nó phải được trả về bởi một lệnh gọi trước đó tới , hoặc
Nếu yêu cầu không thành công, trả về
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1 và p vẫn là một con trỏ hợp lệ tới vùng bộ nhớ trước đóvoid PyMem_Free[void *p]
một phần của
Giải phóng khối bộ nhớ được trỏ tới bởi p, khối này phải được trả về bởi lệnh gọi trước đó tới , hoặc. Mặt khác, hoặc nếu realloc[]
0 đã được gọi trước đó, hành vi không xác định sẽ xảy ra
Nếu p là
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1, không có thao tác nào được thực hiện
Các macro hướng loại sau đây được cung cấp để thuận tiện. Lưu ý rằng LOẠI đề cập đến bất kỳ loại C nào
LOẠI *PyMem_New[LOẠI, size_t n]Tương tự như , nhưng phân bổ _______105_______3 byte bộ nhớ. Trả về một con trỏ được truyền tới TYPE* . Bộ nhớ sẽ không được khởi tạo theo bất kỳ cách nào.
LOẠI *PyMem_Resize[void *p, TYPE, size_t n]Tương tự như , nhưng khối bộ nhớ được thay đổi kích thước thành realloc[]
3 byte. Trả về một con trỏ được truyền tới TYPE* . Khi quay lại, p sẽ là một con trỏ tới vùng bộ nhớ mới hoặc
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1 trong trường hợp thất bại.
Đây là macro tiền xử lý C; . Lưu giá trị ban đầu của p để tránh mất bộ nhớ khi xử lý lỗi
void PyMem_Del[void *p]Giống như
Ngoài ra, các bộ macro sau được cung cấp để gọi trực tiếp bộ cấp phát bộ nhớ Python mà không liên quan đến các hàm API C được liệt kê ở trên. Tuy nhiên, lưu ý rằng việc sử dụng chúng không duy trì khả năng tương thích nhị phân trên các phiên bản Python và do đó không được dùng trong các mô-đun mở rộng
realloc[]
8realloc[]
9free[]
0free[]
1free[]
2free[]
3
Cấp phát đối tượng
Các bộ chức năng sau đây, được lập mô hình theo tiêu chuẩn ANSI C, nhưng chỉ định hành vi khi yêu cầu byte bằng 0, có sẵn để cấp phát và giải phóng bộ nhớ khỏi heap Python
Ghi chú
Không có gì đảm bảo rằng bộ nhớ do các bộ cấp phát này trả về có thể được truyền thành công tới một đối tượng Python khi chặn các hàm cấp phát trong miền này bằng các phương pháp được mô tả trong phần
Việc sử dụng
Cảnh báo
Phải được tổ chức khi sử dụng các chức năng này
void *PyObject_Malloc[size_t n]một phần của
Cấp phát n byte và trả về một con trỏ loại void* cho bộ nhớ được cấp phát hoặc
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1 .
Yêu cầu các byte bằng 0 trả về một con trỏ khác biệt không phải ____2_______1 nếu có thể, như thể thay vào đó, free[]
6 đã được gọi. Bộ nhớ sẽ không được khởi tạo theo bất kỳ cách nào
Một phần của kể từ phiên bản 3. 7
Cấp phát các phần tử nelem, mỗi phần tử có kích thước theo byte là elsize và trả về một con trỏ loại void* . Bộ nhớ được khởi tạo bằng không.
Yêu cầu các phần tử bằng 0 hoặc các phần tử có kích thước byte bằng 0 trả về một con trỏ không phải ______2_______1 riêng biệt nếu có thể, như thể thay vào đó, free[]
9 đã được gọi
Mới trong phiên bản 3. 5
void *PyObject_Realloc[void *p, size_t n]một phần của
Thay đổi kích thước khối bộ nhớ được trỏ tới bởi p thành n byte. Nội dung sẽ không thay đổi ở mức tối thiểu của kích thước cũ và mới
Nếu p là
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1, cuộc gọi tương đương với
PYTHONMALLOC
1; Trừ khi p là
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1, nó phải được trả về bởi một lệnh gọi trước đó tới , hoặc
Nếu yêu cầu không thành công, trả về
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1 và p vẫn là một con trỏ hợp lệ tới vùng bộ nhớ trước đóvoid PyObject_Free[void *p]
một phần của
Giải phóng khối bộ nhớ được trỏ tới bởi p, khối này phải được trả về bởi lệnh gọi trước đó tới , hoặc. Mặt khác, hoặc nếu PYTHONMALLOCSTATS
2 đã được gọi trước đó, hành vi không xác định sẽ xảy ra
Nếu p là
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;1, không có thao tác nào được thực hiện
Bộ cấp phát bộ nhớ mặc định
Bộ cấp phát bộ nhớ mặc định
Cấu hình
Tên
PyMem_RawMalloc
PyMem_Malloc
PyObject_Malloc
Phát hành bản dựng
PYTHONMALLOCSTATS
4
PYTHONMALLOCSTATS
5
PYTHONMALLOCSTATS
6
PYTHONMALLOCSTATS
6
bản dựng gỡ lỗi
PYTHONMALLOCSTATS
8
PYTHONMALLOCSTATS
5 + gỡ lỗi
PYTHONMALLOCSTATS
6 + gỡ lỗi
PYTHONMALLOCSTATS
6 + gỡ lỗi
Phát hành bản dựng, không có pymalloc
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;02
PYTHONMALLOCSTATS
5
PYTHONMALLOCSTATS
5
PYTHONMALLOCSTATS
5
Bản dựng gỡ lỗi, không có pymalloc
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;06
PYTHONMALLOCSTATS
5 + gỡ lỗi
PYTHONMALLOCSTATS
5 + gỡ lỗi
PYTHONMALLOCSTATS
5 + gỡ lỗi
Huyền thoại
Tên. giá trị cho biến môi trường
PYTHONMALLOCSTATS
5. bộ cấp phát hệ thống từ thư viện C tiêu chuẩn, hàm C.malloc[]
,calloc[]
,realloc[]
vàfree[]
PYTHONMALLOCSTATS
6.“+ gỡ lỗi”. với
“Bản dựng gỡ lỗi”.
Tùy chỉnh cấp phát bộ nhớ
Mới trong phiên bản 3. 4
type PyMemAllocatorExCấu trúc được sử dụng để mô tả bộ cấp phát khối bộ nhớ. Cấu trúc có các trường sau
Đồng ruộng
Nghĩa
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;17
ngữ cảnh người dùng được chuyển làm đối số đầu tiên
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;18
phân bổ một khối bộ nhớ
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;19
phân bổ một khối bộ nhớ được khởi tạo bằng số không
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;20
phân bổ hoặc thay đổi kích thước khối bộ nhớ
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;21
giải phóng một khối bộ nhớ
Đã thay đổi trong phiên bản 3. 5. Cấu trúc
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;22 đã được đổi tên thành và một trường
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;24 mới đã được thêm vào. type PyMemAllocatorDomain
Enum được sử dụng để xác định miền cấp phát. tên miền
PYMEM_DOMAIN_RAWChức năng
Chức năng
,
Chức năng
Nhận bộ cấp phát khối bộ nhớ của miền đã chỉ định
void PyMem_SetAllocator[ miền , *allocator]Đặt bộ cấp phát khối bộ nhớ của miền đã chỉ định
Bộ cấp phát mới phải trả về một con trỏ không phải ______2_______1 riêng biệt khi yêu cầu byte bằng 0
Đối với miền
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;38, bộ cấp phát phải an toàn theo luồng. cái không được giữ khi bộ cấp phát được gọi
Nếu bộ cấp phát mới không phải là hook [không gọi bộ cấp phát trước đó], hàm phải được gọi để cài đặt lại các hook gỡ lỗi ở trên cùng trên bộ cấp phát mới
Xem thêm và
Cảnh báo
có hợp đồng sau
void PyMem_SetupDebugHooks[void]
Nó có thể được gọi sau và trước để cài đặt bộ cấp phát bộ nhớ tùy chỉnh. Không có hạn chế nào đối với bộ cấp phát đã cài đặt ngoài những hạn chế do miền áp đặt [ví dụ: Miền thô cho phép gọi bộ cấp phát mà không cần giữ GIL]. Xem để biết thêm thông tin
Nếu được gọi sau khi Python khởi tạo xong [sau khi đã được gọi], bộ cấp phát phải bọc bộ cấp phát hiện có. Thay thế bộ cấp phát hiện tại cho một số tùy ý khác không được hỗ trợ
Thiết lập để phát hiện lỗi bộ nhớ
Gỡ lỗi móc trên bộ cấp phát bộ nhớ Python
Khi nào, hàm được gọi để thiết lập móc gỡ lỗi trên bộ cấp phát bộ nhớ Python để phát hiện lỗi bộ nhớ
Biến môi trường có thể được sử dụng để cài đặt móc gỡ lỗi trên Python được biên dịch ở chế độ phát hành [ví dụ:.
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;47]
Chức năng này có thể được sử dụng để đặt móc gỡ lỗi sau khi gọi
Các móc gỡ lỗi này lấp đầy các khối bộ nhớ được cấp phát động bằng các mẫu bit đặc biệt, dễ nhận biết. Bộ nhớ mới được cấp phát chứa đầy byte
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;50 [
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;51], bộ nhớ được giải phóng chứa đầy byte
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;52 [
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;53]. Các khối bộ nhớ được bao quanh bởi “các byte bị cấm” chứa đầy byte
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;54 [
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;55]. Các chuỗi byte này không có khả năng là địa chỉ hợp lệ, số float hoặc chuỗi ASCII
kiểm tra thời gian chạy
Phát hiện vi phạm API. Ví dụ: phát hiện xem có được gọi trên khối bộ nhớ được cấp phát bởi
Phát hiện ghi trước khi bắt đầu bộ đệm [chảy tràn bộ đệm]
Phát hiện ghi sau khi kết thúc bộ đệm [tràn bộ đệm]
Kiểm tra xem the có được giữ khi chức năng cấp phát của
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;
58 [ví dụ:. ] vàPyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;
60 [ví dụ:. ] tên miền được gọi
Khi xảy ra lỗi, móc gỡ lỗi sử dụng mô-đun để truy xuất nguồn gốc nơi một khối bộ nhớ được phân bổ. Traceback chỉ được hiển thị nếu đang theo dõi phân bổ bộ nhớ Python và khối bộ nhớ đã được theo dõi
Đặt S =
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;64.
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;65 byte được thêm vào mỗi đầu của mỗi khối N byte được yêu cầu. Bố cục bộ nhớ giống như vậy, trong đó p đại diện cho địa chỉ được trả về bởi một hàm giống malloc hoặc realloc [_______1_______66 có nghĩa là lát byte từ bao gồm
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;67 đến loại trừ
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;68; lưu ý rằng cách xử lý các chỉ số âm khác với lát Python
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;69
Số byte ban đầu được yêu cầu. Đây là size_t, big-endian [dễ đọc hơn trong kết xuất bộ nhớ]
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;70
Mã định danh API [ký tự ASCII]
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;
71 choPyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;
38PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;
73 choPyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;
60PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;
75 choPyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;
58
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;77
Bản sao của PYMEM_FORBIDDENBYTE. Được sử dụng để bắt ghi dưới và đọc
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;78
Bộ nhớ được yêu cầu, chứa đầy các bản sao của PYMEM_CLEANBYTE, được sử dụng để bắt tham chiếu đến bộ nhớ chưa được khởi tạo. Khi một hàm giống realloc được gọi yêu cầu khối bộ nhớ lớn hơn, các byte dư thừa mới cũng được lấp đầy bằng PYMEM_CLEANBYTE. Khi một chức năng giống như tự do được gọi, chúng sẽ được ghi đè bằng PYMEM_DEADBYTE, để bắt tham chiếu đến bộ nhớ được giải phóng. Khi một chức năng giống như realloc được gọi yêu cầu một khối bộ nhớ nhỏ hơn, các byte cũ dư thừa cũng được lấp đầy bằng PYMEM_DEADBYTE
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;79
Bản sao của PYMEM_FORBIDDENBYTE. Được sử dụng để ghi đè và đọc
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;80
Chỉ được sử dụng nếu macro
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;81 được xác định [không được xác định theo mặc định]
Một số sê-ri, được tăng thêm 1 trên mỗi lần gọi hàm giống malloc hoặc giống realloc. Big-endian
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;82. Nếu “bộ nhớ kém” được phát hiện sau đó, số sê-ri sẽ cung cấp một cách tuyệt vời để đặt điểm dừng trong lần chạy tiếp theo, để ghi lại khoảnh khắc mà khối này được chuyển đi. Hàm tĩnh bumpserialno[] trong obmalloc. c là nơi duy nhất số sê-ri được tăng lên và tồn tại để bạn có thể dễ dàng đặt điểm dừng như vậy
Trước tiên, chức năng giống như realloc hoặc giống như tự do sẽ kiểm tra xem các byte PYMEM_FORBIDDENBYTE ở mỗi đầu có còn nguyên vẹn không. Nếu chúng đã bị thay đổi, đầu ra chẩn đoán được ghi vào thiết bị lỗi chuẩn và chương trình bị hủy bỏ qua Py_FatalError[]. Chế độ lỗi chính khác đang gây ra lỗi bộ nhớ khi chương trình đọc một trong các mẫu bit đặc biệt và cố gắng sử dụng nó làm địa chỉ. Sau đó, nếu bạn vào trình gỡ lỗi và nhìn vào đối tượng, bạn có thể thấy rằng nó hoàn toàn chứa đầy PYMEM_DEADBYTE [có nghĩa là bộ nhớ được giải phóng đang được sử dụng] hoặc PYMEM_CLEANBYTE [có nghĩa là bộ nhớ chưa được khởi tạo đang được sử dụng]
Đã thay đổi trong phiên bản 3. 6. Hàm này hiện cũng hoạt động trên Python được biên dịch ở chế độ phát hành. Khi có lỗi, các móc gỡ lỗi hiện sử dụng để truy xuất nguồn gốc nơi một khối bộ nhớ được phân bổ. Các móc gỡ lỗi hiện cũng kiểm tra xem GIL có được giữ hay không khi các chức năng của tên miền
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;58 và
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;60 được gọi.
Đã thay đổi trong phiên bản 3. 8. Các mẫu byte
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;87 [
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;51],
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;89 [
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;53] và
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;91 [
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;55] đã được thay thế bằng
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;50,
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;52 và
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;54 để sử dụng các giá trị giống như Windows CRT debug
malloc[]
và free[]
. Bộ cấp phát pymalloc
Python có bộ cấp phát pymalloc được tối ưu hóa cho các đối tượng nhỏ [nhỏ hơn hoặc bằng 512 byte] với thời gian tồn tại ngắn. Nó sử dụng ánh xạ bộ nhớ được gọi là "đấu trường" với kích thước cố định là 256 KiB. Nó quay trở lại và dành cho phân bổ lớn hơn 512 byte
pymalloc là của
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;60 [ví dụ:. ] và
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;58 [ví dụ:. ] tên miền
Bộ phân bổ đấu trường sử dụng các chức năng sau
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;
04 vàPyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;
05 trên Windows,PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;
06 vàPyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;
07 nếu có,malloc[]
vàfree[]
ngược lại
Trình cấp phát này bị tắt nếu Python được định cấu hình với tùy chọn. Nó cũng có thể bị vô hiệu hóa trong thời gian chạy bằng cách sử dụng biến môi trường [ví dụ:.
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;12]
Tùy chỉnh Trình phân bổ đấu trường pymalloc
Mới trong phiên bản 3. 4
loại PyObjectArenaAllocatorCấu trúc được sử dụng để mô tả một bộ phân bổ đấu trường. Cấu trúc có ba trường
Đồng ruộng
Nghĩa
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;17
ngữ cảnh người dùng được chuyển làm đối số đầu tiên
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;14
phân bổ một đấu trường có kích thước byte
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;15
giải phóng một đấu trường
void PyObject_GetArenaAllocator[ *cấp phát]Nhận phân bổ đấu trường
void PyObject_SetArenaAllocator[ *cấp phát]Đặt bộ phân bổ đấu trường
API tramalloc C
Mới trong phiên bản 3. 7
int PyTraceMalloc_Track[unsigned int domain, uintptr_t ptr, size_t size]Theo dõi một khối bộ nhớ được phân bổ trong mô-đun
Trả về
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;17 nếu thành công, trả về
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;18 nếu lỗi [không thể cấp phát bộ nhớ để lưu dấu vết]. Trả lại
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;19 nếu dấu vết bị vô hiệu hóa
Nếu khối bộ nhớ đã được theo dõi, hãy cập nhật dấu vết hiện có
int PyTraceMalloc_Untrack[unsigned int domain, uintptr_t ptr]Bỏ theo dõi một khối bộ nhớ được phân bổ trong mô-đun. Không làm gì nếu khối không được theo dõi
Trả lại
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;19 nếu tracemalloc bị vô hiệu hóa, nếu không thì trả lại
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;17
ví dụ
Đây là ví dụ từ phần , được viết lại để bộ đệm I/O được phân bổ từ vùng heap Python bằng cách sử dụng tập hàm đầu tiên
PyObject *res; char *buf = [char *] PyMem_Malloc[BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Free[buf]; /* allocated with PyMem_Malloc */ return res;
Mã tương tự sử dụng bộ chức năng định hướng kiểu
PyObject *res; char *buf = PyMem_New[char, BUFSIZ]; /* for I/O */ if [buf == NULL] return PyErr_NoMemory[]; /* ...Do some I/O operation involving buf.. */ res = PyBytes_FromString[buf]; PyMem_Del[buf]; /* allocated with PyMem_New */ return res;
Lưu ý rằng trong hai ví dụ trên, bộ đệm luôn được thao tác thông qua các hàm thuộc cùng một tập hợp. Thật vậy, bắt buộc phải sử dụng cùng một họ API bộ nhớ cho một khối bộ nhớ nhất định, để rủi ro trộn lẫn các bộ cấp phát khác nhau được giảm đến mức tối thiểu. Chuỗi mã sau có hai lỗi, một trong số đó được gắn nhãn là nghiêm trọng vì nó trộn lẫn hai trình cấp phát khác nhau hoạt động trên các vùng khác nhau
char *buf1 = PyMem_New[char, BUFSIZ]; char *buf2 = [char *] malloc[BUFSIZ]; char *buf3 = [char *] PyMem_Malloc[BUFSIZ]; ... PyMem_Del[buf3]; /* Wrong -- should be PyMem_Free[] */ free[buf2]; /* Right -- allocated via malloc[] */ free[buf1]; /* Fatal -- should be PyMem_Del[] */
Ngoài các chức năng nhằm xử lý các khối bộ nhớ thô từ heap Python, các đối tượng trong Python được cấp phát và giải phóng với , và