Python có thể chứa bao nhiêu dữ liệu trong bộ nhớ?

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[]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[]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ào

void *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[].

void *PyMem_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ô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

void *PyMem_Calloc[size_t nelem, size_t elsize]
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[]8

  • realloc[]9

  • free[]0

  • free[]1

  • free[]2

  • free[]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

void *PyObject_Calloc[size_t nelem, size_t elsize]
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 PYTHONMALLOC1;

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 PYTHONMALLOCSTATS2 đã đượ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

PYTHONMALLOCSTATS4

PYTHONMALLOCSTATS5

PYTHONMALLOCSTATS6

PYTHONMALLOCSTATS6

bản dựng gỡ lỗi

PYTHONMALLOCSTATS8

PYTHONMALLOCSTATS5 + gỡ lỗi

PYTHONMALLOCSTATS6 + gỡ lỗi

PYTHONMALLOCSTATS6 + 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

PYTHONMALLOCSTATS5

PYTHONMALLOCSTATS5

PYTHONMALLOCSTATS5

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

PYTHONMALLOCSTATS5 + gỡ lỗi

PYTHONMALLOCSTATS5 + gỡ lỗi

PYTHONMALLOCSTATS5 + gỡ lỗi

Huyền thoại

  • Tên. giá trị cho biến môi trường

  • PYTHONMALLOCSTATS5. bộ cấp phát hệ thống từ thư viện C tiêu chuẩn, hàm C. malloc[], calloc[], realloc[]free[]

  • PYTHONMALLOCSTATS6.

  • “+ 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 PyMemAllocatorEx

Cấ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_RAW

Chức năng

PYMEM_DOMAIN_MEM

Chức năng

  • ,

PYMEM_DOMAIN_OBJ

Chức năng

void PyMem_GetAllocator[ miền , *allocator]

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

  • 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ợ

void PyMem_SetupDebugHooks[void]

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 cho
    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

  • 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;
    
    73 cho
    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

  • 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;
    
    75 cho
    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

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[]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[]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 PyObjectArenaAllocator

Cấ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à

Python có thể sử dụng bao nhiêu bộ nhớ?

Những số đó có thể dễ dàng khớp với số nguyên 64 bit, vì vậy người ta hy vọng Python sẽ lưu trữ một triệu số nguyên đó trong không quá ~8MB. một triệu đối tượng 8 byte. Trên thực tế, Python sử dụng nhiều hơn như 35 MB RAM để lưu trữ những con số này. Tại sao? .

Python có lưu trữ dữ liệu trong bộ nhớ không?

Tất cả các đối tượng Python và cấu trúc dữ liệu được lưu trữ trong vùng riêng tư . Hệ điều hành không thể phân bổ phần bộ nhớ này cho một tiến trình khác. Kích thước của private heap có thể tăng và giảm dựa trên yêu cầu bộ nhớ của quy trình Python.

Python có hết bộ nhớ không?

Lỗi bộ nhớ có nghĩa là trình thông dịch đã hết bộ nhớ để phân bổ cho chương trình Python của bạn . Điều này có thể là do sự cố trong quá trình thiết lập môi trường Python hoặc có thể do bản thân mã tải quá nhiều dữ liệu cùng một lúc.

Bộ nhớ được lưu trữ như thế nào trong Python?

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 .

Chủ Đề