Hướng dẫn can you dynamically allocate memory in python? - bạn có thể cấp phát bộ nhớ động trong python không?

Tương đương với "mới" trong Python là chỉ sử dụng một hàm tạo, ví dụ:

new_list = list() # or [] - expandable heterogeneous list
new_dict = dict() # expandable hash table
new_obj = CustomObject() # assuming CustomObject has been defined

Vì bạn đang chuyển từ C, một số điều cần lưu ý. Tất cả mọi thứ là một đối tượng trong Python bao gồm các số nguyên và hầu hết các biến chỉ là tài liệu tham khảo, nhưng các quy tắc cho các biến vô hướng như số nguyên và chuỗi khác với các thùng chứa, ví dụ: ví dụ::

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2

However:

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']

Bạn có thể phân bổ trước kích thước, nếu bạn muốn nhưng nó thường không mua cho bạn nhiều lợi ích trong Python. Điều sau đây là hợp lệ:

new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items

Nếu bạn muốn đảm bảo rò rỉ bộ nhớ không xảy ra, hãy sử dụng các biến cục bộ thường xuyên nhất có thể, ví dụ, trong một hàm để mọi thứ đi ra khỏi phạm vi, bạn không phải lo lắng.

Đối với các hoạt động vector hóa hiệu quả (và dấu chân bộ nhớ thấp hơn nhiều) sử dụng các mảng numpy.

import numpy as np
my_array = np.zeros(8192) # create a fixed array length of 8K elements
my_array += 4             # fills everything with 4

Tôi đã thêm hai xu: Có lẽ tôi sẽ bắt đầu bằng cách hỏi mục tiêu chính của bạn là gì. Có những cách làm pythonic, trong khi cố gắng tối ưu hóa tốc độ thực hiện chương trình hoặc dấu chân bộ nhớ tối thiểu. Và sau đó là nỗ lực cố gắng chuyển một chương trình trong càng ít thời gian càng tốt. Đôi khi tất cả chúng giao nhau nhưng thường xuyên hơn, bạn sẽ tìm ra cách pythonic để nhanh chóng dịch nhưng với các yêu cầu bộ nhớ cao hơn. Nhận được hiệu suất cao hơn từ Python có thể sẽ có kinh nghiệm tập trung. Chúc may mắn!

Tổng quan¶

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. Trình quản lý bộ nhớ Python có các thành phần khác nhau liên quan đến các khía cạnh quản lý lưu trữ động khác nhau, như chia sẻ, phân khúc, phân tách hoặc bộ nhớ đệm.

Ở cấp độ thấp nhất, bộ phân bổ bộ nhớ thô đảm bảo rằng có đủ chỗ trong đống riêng để 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ộ phân bổ bộ nhớ thô, một số bộ phân bổ dành riêng cho đối tượng hoạt động trên cùng một đống và thực hiện các chính sách quản lý bộ nhớ riêng biệt thích nghi với đặc thù của mọi loại đối tượng. Ví dụ, các đối tượng số nguyên được quản lý khác nhau trong đống so với chuỗi, bộ dữ liệu hoặc từ điển vì các số nguyên ngụ ý các yêu cầu lưu trữ khác nhau và đánh đổi 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 các phân bổ dành riêng cho đối tượng, nhưng đảm bảo rằng phần sau hoạt động trong giới hạn của đống riêng tư.

Điều quan trọng là phải hiểu rằng việc quản lý đống Python được thực hiện bởi chính người phiên 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úng các con trỏ đối tượng vào các khối bộ nhớ bên trong đống đó. Việc phân bổ không gian heap cho các đối tượng Python và các bộ đệm nội bộ khác được thực hiện theo yêu cầu của Trình quản lý bộ nhớ Python thông qua các hàm API Python/C được liệt kê trong tài liệu này.

Để tránh tham nhũng bộ nhớ, các nhà văn mở rộng không bao giờ nên cố gắng hoạt động trên các đối tượng Python với các chức năng được xuất bởi thư viện C: malloc(),

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
0,
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
1 và
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
2. Điều này sẽ dẫn đến các cuộc gọi hỗn hợp giữa Trình phân bổ C và Trình quản lý bộ nhớ Python với hậu quả nghiêm trọng, bởi vì họ thực hiện các thuật toán khác nhau và hoạt động trên các đống khác nhau. Tuy nhiên, người ta có thể phân bổ và giải phóng các khối bộ nhớ một cách an toàn với Trình phân bổ thư viện C cho các mục đích riêng lẻ, như được hiển thị 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 Trình phân bổ thư viện C. Trình quản lý bộ nhớ Python chỉ tham gia vào việc phân bổ đối tượng byte được trả về.

Tuy nhiên, trong hầu hết các tình huống, nên phân bổ bộ nhớ từ đống Python cụ thể vì cái sau 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ụ thể cao, việc ủy ​​thác tất cả các yêu cầu bộ nhớ cho Trình quản lý bộ nhớ Python khiến trình thông dịch có toàn bộ hình ảnh chính xác hơn về dấu chân 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ể hoặc không thể 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 thủ tục phòng ngừa khác. Lưu ý rằng bằng cách sử dụng trình phân bổ thư viện C như trong ví dụ trước, bộ nhớ được phân bổ cho bộ đệm I/O thoát hoàn toàn Trình quản lý bộ nhớ Python.

Xem thêm

Biến môi trường

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
3 có thể được sử dụng để định cấu hình các bộ phân bổ bộ nhớ được sử dụng bởi Python.
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
3 environment variable can be used to configure the memory allocators used by Python.

Biến môi trường

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
4 có thể được sử dụng để in số liệu thống kê của bộ phân bổ bộ nhớ Pymalloc mỗi khi một đấu trường đối tượng Pymalloc mới được tạo và khi tắt máy.
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
4 environment variable can be used to print statistics of the pymalloc memory allocator every time a new pymalloc object arena is created, and on shutdown.

Miền phân cấp

Tất cả các chức năng phân bổ thuộc về một trong ba tên miền khác nhau (xem thêm

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
5). Các lĩnh vực 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. Các chi tiết cụ thể về cách mọi miền phân bổ bộ nhớ hoặc các chức năng bên trong mà mỗi miền gọi được coi là một chi tiết triển khai, nhưng với mục đích gỡ lỗi, một bảng đơn giản có thể được tìm thấy tại đây. Không có yêu cầu khó khăn để sử dụng bộ nhớ được trả về bởi các hàm phân bổ 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à thực tiễn được đề xuất). Ví dụ, người ta có thể sử dụng bộ nhớ được trả về bởi
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
6 để phân bổ các đối tượng Python hoặc bộ nhớ được trả về bởi
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
7 để phân bổ bộ nhớ cho bộ đệm.here. There is no hard requirement to use the memory returned by the allocation functions belonging to a given domain for only the purposes hinted by that domain (although this is the recommended practice). For example, one could use the memory returned by
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
6 for allocating Python objects or the memory returned by
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
7 for allocating memory for buffers.

Ba miền phân bổ là:

  • Tên miền RAW: Dự định phân bổ bộ nhớ cho bộ đệm bộ nhớ có mục đích chung trong đó phân bổ phải đi đến trình phân bổ hệ thống hoặc nơi bộ phân bổ có thể hoạt động mà không cần Gil. Bộ nhớ được yêu cầu trực tiếp đến hệ thống.GIL. The memory is requested directly to the system.

  • Tên miền MEM MEM: dự định phân bổ bộ nhớ cho bộ đệm python và bộ đệm bộ nhớ đa năng trong đó phân bổ phải được thực hiện với GIL được giữ. Bộ nhớ được lấy từ đống riêng Python.GIL held. The memory is taken from the Python private heap.

  • Miền đối tượng: dự định phân bổ bộ nhớ thuộc về các đối tượng Python. Bộ nhớ được lấy từ đống riêng Python.

Khi giải phóng bộ nhớ được phân bổ trước đây bởi các hàm phân bổ thuộc một miền nhất định, phải sử dụng các chức năng giải quyết cụ thể phù hợp. Ví dụ,

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
8 phải được sử dụng để phân bổ bộ nhớ miễn phí bằng
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
9.

Giao diện bộ nhớ thô

Các bộ chức năng sau đây là trình bao bọc cho bộ phân bổ hệ thống. Các chức năng này là an toàn cho luồng, GIL không cần phải được giữ.GIL does not need to be held.

Bộ phân bổ bộ nhớ thô mặc định sử dụng các chức năng sau: malloc(),

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
0,
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
1 và
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
2; Gọi
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
4 (hoặc
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
5) khi yêu cầu 0 byte.default raw memory allocator uses the following functions: malloc(),
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
0,
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
1 and
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
2; call
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
4 (or
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
5) when requesting zero bytes.

Mới trong phiên bản 3.4.

void* pymem_rawmalloc (size_tn) ¶allobated n byte và trả về một con trỏ khoảng trống* cho bộ nhớ được phân bổ hoặc
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 nếu yêu cầu không thành công.
*PyMem_RawMalloc(size_tn)

Allocates n bytes and returns a pointer of type void* to the allocated memory, or

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 if the request fails.

Yêu cầu số byte không trả về một con trỏ không khác nhau nếu có thể, như thể

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
8 đã được gọi thay thế. Bộ nhớ sẽ không được khởi tạo theo bất kỳ cách nào.

void* pymem_rawcalloc (size_tnelem, size_telsize) ướp phân các phần tử nelem mỗi phần có kích thước trong byte là elsize và trả về một con trỏ khoảng trống* cho bộ nhớ được phân bổ, hoặc
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 nếu yêu cầu không thành công. Bộ nhớ được khởi tạo thành số không.
*PyMem_RawCalloc(size_tnelem, size_telsize)

Allocates nelem elements each whose size in bytes is elsize and returns a pointer of type void* to the allocated memory, or

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 if the request fails. The memory is initialized to zeros.

Yêu cầu các phần tử bằng 0 hoặc các phần tử có kích thước 0 byte trả về một con trỏ không khác biệt khác nhau nếu có thể, như thể

new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
1 đã được gọi thay thế.

Mới trong phiên bản 3.5.

void*pymem_rawrealloc (void*p, size_tn) ¶resize khối bộ nhớ được trỏ bởi p đến n byte. Các nội dung sẽ không thay đổi ở mức tối thiểu của cũ và kích thước mới. *PyMem_RawRealloc(void*p, size_tn)

Resizes the memory block pointed to by p to n bytes. The contents will be unchanged to the minimum of the old and the new sizes.

Nếu P là

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6, cuộc gọi tương đương với
new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
3; khác nếu N bằng 0, khối bộ nhớ được thay đổi kích thước nhưng không được giải phóng và con trỏ trả về không phải là -________ 26.

Trừ khi p là

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6, nó phải được trả lại bằng một cuộc gọi trước đó cho
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
6,
new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
7 hoặc
new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
8.

Nếu yêu cầu không thành công,

new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
7 sẽ trả về
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 và P vẫn là một con trỏ hợp lệ đến khu vực bộ nhớ trước.

VoidPymem_Rawfree (void*p) ¶Frees khối bộ nhớ được trỏ bởi P, phải được trả lại bởi một cuộc gọi trước đó cho
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
6,
new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
7 hoặc
new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
8. Nếu không, hoặc nếu
import numpy as np
my_array = np.zeros(8192) # create a fixed array length of 8K elements
my_array += 4             # fills everything with 4
4 đã được gọi trước đó, hành vi không xác định xảy ra.
PyMem_RawFree(void*p)

Frees the memory block pointed to by p, which must have been returned by a previous call to

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
6,
new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
7 or
new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
8. Otherwise, or if
import numpy as np
my_array = np.zeros(8192) # create a fixed array length of 8K elements
my_array += 4             # fills everything with 4
4 has been called before, undefined behavior occurs.

Nếu P là

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6, không có hoạt động nào được thực hiện.

Giao diện bộ nhớ

Các bộ chức năng sau, được mô hình hóa theo tiêu chuẩn ANSI C, nhưng chỉ định hành vi khi yêu cầu 0 byte, có sẵn để phân bổ và giải phóng bộ nhớ từ đống Python.

Bộ phân bổ bộ nhớ mặc định sử dụng bộ phân bổ bộ nhớ Pymalloc.default memory allocator uses the pymalloc memory allocator.

Cảnh báo

GIL phải được giữ khi sử dụng các chức năng này.GIL must be held when using these functions.

Đã thay đổi trong phiên bản 3.6: Bộ phân bổ mặc định hiện là pymalloc thay vì hệ thống malloc().The default allocator is now pymalloc instead of system malloc().

void*pymem_malloc (size_tn) một phần của ABI ổn định.*PyMem_Malloc(size_tn)
Part of the Stable ABI.

Phân bổ n byte và trả về một con trỏ khoảng trống* cho bộ nhớ được phân bổ hoặc

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 nếu yêu cầu không thành công.void* to the allocated memory, or
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 if the request fails.

Yêu cầu Zero Byte trả về một con trỏ không khác biệt nếu có thể, như thể

import numpy as np
my_array = np.zeros(8192) # create a fixed array length of 8K elements
my_array += 4             # fills everything with 4
9 đã được gọi thay thế. Bộ nhớ sẽ không được khởi tạo theo bất kỳ cách nào.

void*pymem_calloc (size_tnelem, size_telsize) một phần của ABI ổn định kể từ phiên bản 3.7.*PyMem_Calloc(size_tnelem, size_telsize)
Part of the Stable ABI since version 3.7.

Phân bổ các phần tử nelem, mỗi phần tử có kích thước trong byte là elsize và trả về một con trỏ khoảng trống* cho bộ nhớ được phân bổ hoặc

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 nếu yêu cầu không thành công. Bộ nhớ được khởi tạo thành số không.void* to the allocated memory, or
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 if the request fails. The memory is initialized to zeros.

Yêu cầu các phần tử bằng 0 hoặc các phần tử có kích thước 0 byte trả về một con trỏ không khác biệt khác nhau nếu có thể, như thể

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;
2 đã được gọi thay thế.

Mới trong phiên bản 3.5.

void*pymem_realloc (void*p, size_tn) một phần của ABI ổn định.*PyMem_Realloc(void*p, size_t n)
Part of the Stable ABI.

Thay đổi kích thước khối bộ nhớ được trỏ bởi p thành n byte. Các nội dung sẽ không thay đổi ở mức tối thiểu của cũ và kích thước mới.

Nếu P là

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6, cuộc gọi tương đương với
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;
4; khác nếu N bằng 0, khối bộ nhớ được thay đổi kích thước nhưng không được giải phóng và con trỏ trả về không phải là -________ 26.

Trừ khi p là

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6, nó phải được trả lại bằng một cuộc gọi trước đó cho
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
9,
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;
8 hoặc
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;
9.

Nếu yêu cầu không thành công,

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;
8 sẽ trả về
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 và P vẫn là một con trỏ hợp lệ đến khu vực bộ nhớ trước.

VoidPymem_Free (void*p) Một phần của ABI ổn định. PyMem_Free(void*p)
Part of the Stable ABI.

Giải phóng khối bộ nhớ được chỉ bởi P, phải được trả lại bằng một cuộc gọi trước đó cho

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
9,
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;
8 hoặc
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;
9. Nếu không, hoặc nếu
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;
5 đã được gọi trước đó, hành vi không xác định xảy ra.

Nếu P là

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6, không có hoạt động nào được thực hiện.

Các macro định hướng loại sau đượ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 (gõ, size_tn) ¶ame là
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
9, nhưng phân bổ
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;
8 byte của bộ nhớ. Trả về một con trỏ đúc thành loại*. Bộ nhớ sẽ không được khởi tạo theo bất kỳ cách nào.
*PyMem_New(TYPE, size_t n)

Same as

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
9, but allocates
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;
8 bytes of memory. Returns a pointer cast to TYPE*. The memory will not have been initialized in any way.

Loại*pymem_resize (void*p, type, size_tn) ¶ame dưới dạng
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;
8, nhưng khối bộ nhớ được thay đổi kích thước thành
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;
0 byte. Trả về một con trỏ đúc thành loại*. Khi trở về, P sẽ là một con trỏ đến khu vực bộ nhớ mới hoặc
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 trong trường hợp thất bại.
*PyMem_Resize(void*p, TYPE, size_t n)

Same as

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;
8, but the memory block is resized to
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;
0 bytes. Returns a pointer cast to TYPE*. On return, p will be a pointer to the new memory area, or
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 in the event of failure.

Đây là một macro tiền xử lý C; P luôn được chỉ định lại. Lưu giá trị ban đầu của P để tránh mất bộ nhớ khi xử lý lỗi.

VoidPymem_Del (void*p) ¶ameSme là
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
8.
PyMem_Del(void *p)

Same as

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
8.

Ngoài ra, các bộ macro sau được cung cấp để gọi trực tiếp bộ phân bổ bộ nhớ Python, mà không liên quan đến các hàm A API được liệt kê ở trên. Tuy nhiên, lưu ý rằng việc sử dụng của chúng không bảo tồn 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.

  • 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

  • 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;
    
    4

  • 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;
    
    5

  • 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

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

  • 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

Người phân bổ đối tượng

Các bộ chức năng sau, được mô hình hóa theo tiêu chuẩn ANSI C, nhưng chỉ định hành vi khi yêu cầu 0 byte, có sẵn để phân bổ và giải phóng bộ nhớ từ đống Python.

Ghi chú

Không có gì đảm bảo rằng bộ nhớ được trả về bởi các phân bổ này có thể được chuyển thành công vào một đối tượng Python khi chặn các hàm phân bổ trong miền này bằng các phương thức được mô tả trong phần phân bổ bộ nhớ tùy chỉnh.Customize Memory Allocators section.

Trình phân bổ đối tượng mặc định sử dụng Trình phân bổ bộ nhớ Pymalloc.default object allocator uses the pymalloc memory allocator.

Cảnh báo

GIL phải được giữ khi sử dụng các chức năng này.GIL must be held when using these functions.

void*pyobject_malloc (size_tn) một phần của ABI ổn định.*PyObject_Malloc(size_t n)
Part of the Stable ABI.

Phân bổ n byte và trả về một con trỏ khoảng trống* cho bộ nhớ được phân bổ hoặc

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 nếu yêu cầu không thành công.void* to the allocated memory, or
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 if the request fails.

Yêu cầu Zero Byte trả về một con trỏ không khác biệt nếu có thể, như thể

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()  */
1 đã được gọi thay thế. Bộ nhớ sẽ không được khởi tạo theo bất kỳ cách nào.

void*PyObject_Calloc (size_tnelem, size_telsize) Một phần của ABI ổn định kể từ phiên bản 3.7.*PyObject_Calloc(size_tnelem, size_t elsize)
Part of the Stable ABI since version 3.7.

Phân bổ các phần tử nelem, mỗi phần tử có kích thước trong byte là elsize và trả về một con trỏ khoảng trống* cho bộ nhớ được phân bổ hoặc

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 nếu yêu cầu không thành công. Bộ nhớ được khởi tạo thành số không.void* to the allocated memory, or
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 if the request fails. The memory is initialized to zeros.

Yêu cầu các phần tử bằng 0 hoặc các phần tử có kích thước 0 byte trả về một con trỏ không khác biệt khác nhau nếu có thể, như thể

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()  */
4 đã được gọi thay thế.

Mới trong phiên bản 3.5.

void*pymem_realloc (void*p, size_tn) một phần của ABI ổn định. *PyObject_Realloc(void*p, size_tn)
Part of the Stable ABI.

Thay đổi kích thước khối bộ nhớ được trỏ bởi p thành n byte. Các nội dung sẽ không thay đổi ở mức tối thiểu của cũ và kích thước mới.

Nếu P là

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6, cuộc gọi tương đương với
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;
4; khác nếu N bằng 0, khối bộ nhớ được thay đổi kích thước nhưng không được giải phóng và con trỏ trả về không phải là -________ 26.

Trừ khi p là

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6, nó phải được trả lại bằng một cuộc gọi trước đó cho
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
9,
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;
8 hoặc
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;
9.

Nếu yêu cầu không thành công,

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;
8 sẽ trả về
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6 và P vẫn là một con trỏ hợp lệ đến khu vực bộ nhớ trước.

VoidPymem_Free (void*p) Một phần của ABI ổn định.PyObject_Free(void *p)
Part of the Stable ABI.

Giải phóng khối bộ nhớ được chỉ bởi P, phải được trả lại bằng một cuộc gọi trước đó cho

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
9,
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;
8 hoặc
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;
9. Nếu không, hoặc nếu
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;
5 đã được gọi trước đó, hành vi không xác định xảy ra.

Nếu P là

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
6, không có hoạt động nào được thực hiện.

Phân bổ bộ nhớ mặc định

Bộ phân bổ 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

malloc()9

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
00

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
01

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
01

Gỡ lỗi xây dựng

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
03

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
00 + gỡ lỗi

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
01 + gỡ lỗi

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
01 + gỡ lỗi

Phát hành bản dựng, không có pymalloc

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
07

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
00

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
00

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
00

Gỡ lỗi xây dựng, không có pymalloc

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
11

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
00 + gỡ lỗi

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
00 + gỡ lỗi

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
00 + gỡ lỗi

Legend:

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    01 + gỡ lỗi
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    3 environment variable.

  • Phát hành bản dựng, không có pymalloc

  • Gỡ lỗi xây dựng, không có pymallocpymalloc memory allocator.

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

    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    3.debug hooks on the Python memory allocators.

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    00: Bộ phân bổ hệ thống từ thư viện C tiêu chuẩn, hàm C: malloc(),
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    0,
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    1 và
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    2.Python build in debug mode.

a = 2 # a is a reference to 2 b = a # b is a reference to 'a' b = 3 # b now points to 3, while 'a' continues to point to 2 01: Bộ phân bổ bộ nhớ Pymalloc.

Cấm+ DEBUG: với các móc gỡ lỗi trên các bộ phân bổ bộ nhớ Python.

Build Debug Build Build: Build Python trong chế độ gỡ lỗi.PyMemAllocatorEx

Structure used to describe a memory block allocator. The structure has the following fields:

Tùy chỉnh bộ phận phân bổ bộ nhớ

Mới trong phiên bản 3.4.

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
22

TypePymemallocatorex¶ cấu trúc được sử dụng để mô tả bộ phân bổ khối bộ nhớ. Cấu trúc có các trường sau:

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
23

Đồng ruộng

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
24

Nghĩa

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
25

Bối cảnh người dùng được thông qua như đối số đầu tiên

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
26

Phân bổ một khối bộ nhớ

Phân bổ một khối bộ nhớ được khởi tạo bằng các số khôngThe

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
27 structure was renamed to
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
28 and a new
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
29 field was added.

Phân bổ hoặc thay đổi kích thước khối bộ nhớ PyMemAllocatorDomain

Enum used to identify an allocator domain. Domains:

Miễn phí một khối bộ nhớ

Functions:

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    6

  • new_list4k = [None]*4096 # initialize to list of 4096 None's 
    new_list4k = [0]*4096    # initialize to 4096 0's
    big_list = []
    big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
    
    7

  • new_list4k = [None]*4096 # initialize to list of 4096 None's 
    new_list4k = [0]*4096    # initialize to 4096 0's
    big_list = []
    big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
    
    8

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    33

Thay đổi trong phiên bản 3.5: Cấu trúc
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
27 được đổi tên thành
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
28 và trường
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
29 mới đã được thêm vào.

Functions:

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    9,

  • 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;
    
    8

  • 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;
    
    9

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    8

TypePyMemallocatordomain¶enum được sử dụng để xác định miền phân bổ. Miền:

Functions:

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    7

  • malloc()0

  • malloc()1

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    41

Pymem_domain_raw¶fnes:PyMem_GetAllocator(PyMemAllocatorDomaindomain, PyMemAllocatorEx *allocator)

Get the memory block allocator of the specified domain.

Pymem_domain_mem¶fnes: PyMem_SetAllocator(PyMemAllocatorDomaindomain, PyMemAllocatorEx *allocator)

Set the memory block allocator of the specified domain.

Pymem_domain_obj¶fnes:

VoidPymem_Getallocator (pymemallocatordomaindomain, pymemallocatorex*ALLOCATOR) Ăn bộ phân bổ khối bộ nhớ của miền được chỉ định.GIL is not held when the allocator is called.

Voidpymem_setallocator (PymemallocatorDomAINDOMAIN, PYMEMALLOCATOREX*ALLOCATOR) ¶ Set Trình phân bổ khối bộ nhớ của miền được chỉ định.

Bộ phân bổ mới phải trả về một con trỏ không khác nhau khi yêu cầu số không byte.Preinitialize Python with PyPreConfig.

Đối với miền

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
43, bộ phân bổ phải an toàn cho luồng: GIL không được giữ khi bộ phân bổ được gọi.

Nếu bộ phân bổ mới không phải là một móc (không gọi trình phân bổ trước đó), hàm

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
44 phải được gọi để cài đặt lại các móc gỡ lỗi trên đầu trên trình phân bổ mới.

  • Xem thêm

    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    45 và preinitialize python với pypreconfig.the section on allocator domains for more information.

  • Cảnh báomust wrap the existing allocator. Substituting the current allocator for some other arbitrary one is not supported.

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
46 có hợp đồng sau:
PyMem_SetupDebugHooks(void)

Setup debug hooks in the Python memory allocators to detect memory errors.

Nó có thể được gọi sau a = 2 # a is a reference to 2 b = a # b is a reference to 'a' b = 3 # b now points to 3, while 'a' continues to point to 2 47 và trước a = 2 # a is a reference to 2 b = a # b is a reference to 'a' b = 3 # b now points to 3, while 'a' continues to point to 2 48 để cài đặt bộ phân bổ bộ nhớ tùy chỉnh. Không có giới hạn đối với bộ phân bổ được cài đặt khác với các bộ phân bổ được áp đặt bởi tên miền (ví dụ, miền RAW cho phép bộ phân bổ được gọi mà không cần GiL giữ). Xem phần trên các miền phân bổ để biết thêm thông tin.

Nếu được gọi sau khi Python đã hoàn thành khởi tạo (sau khi

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
48 được gọi), bộ phân bổ phải bọc bộ phân bổ hiện có. Thay thế bộ phân bổ hiện tại cho một số tùy ý khác không được hỗ trợ.Python is built in debug mode, the
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
44 function is called at the Python preinitialization to setup debug hooks on Python memory allocators to detect memory errors.

Voidpymem_setupdebughooks (void) ¶setUp Debug Hook trong các trình phân bổ bộ nhớ Python để phát hiện các lỗi bộ nhớ.

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
3 environment variable can be used to install debug hooks on a Python compiled in release mode (ex:
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
52).

Gỡ lỗi móc vào bộ phân bổ bộ nhớ Python

Khi Python được xây dựng ở chế độ gỡ lỗi, hàm

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
44 được gọi là python preinitialization để thiết lập các móc gỡ lỗi trên các bộ phân bổ bộ nhớ python để phát hiện lỗi bộ nhớ.

Biến môi trường

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
3 có thể được sử dụng để cài đặt các móc gỡ lỗi trên một python được biên dịch trong chế độ phát hành (ví dụ:
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
52).

  • Hàm

    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    44 có thể được sử dụng để đặt các móc gỡ lỗi sau khi gọi
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    46.

  • Các móc gỡ lỗi này lấp đầy các khối bộ nhớ được phân bổ động với các mẫu bit đặc biệt, dễ nhận biết. Bộ nhớ mới được phân bổ được lấp đầy bằng byte

    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    55 (
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    56), bộ nhớ được giải phóng được lấp đầy bằng byte
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    57 (
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    58). Các khối bộ nhớ được bao quanh bởi các byte bị cấm của các byte, chứa đầy byte
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    59 (
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    60). Các chuỗi của các byte này khó có thể là các địa chỉ, phao hoặc chuỗi ASCII hợp lệ.

  • Kiểm tra thời gian chạy:

  • Phát hiện vi phạm API. Ví dụ: phát hiện nếu

    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    41 được gọi trên khối bộ nhớ được phân bổ bởi
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    9.GIL is held when allocator functions of
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    63 (ex:
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    7) and
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    65 (ex:
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    9) domains are called.

Phát hiện ghi trước khi bắt đầu bộ đệm (bộ đệm dưới dòng).

Phát hiện ghi sau khi kết thúc bộ đệm (tràn bộ đệm).

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
74

Số byte ban đầu yêu cầu. Đây là một size_t, Big-endian (dễ đọc hơn trong kết xuất bộ nhớ).

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
75

Định danh API (ký tự ASCII):

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    76 cho
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    43.

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    78 cho
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    65.

  • a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    80 cho
    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    63.

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
82

Bản sao của pymem_forbiddenbyte. Được sử dụng để bắt dưới và đọc.

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
83

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ớ không được hưởng. Khi một hàm giống như realloc được gọi là yêu cầu một khối bộ nhớ lớn hơn, các byte vượt quá mới cũng được lấp đầy bằng pymem_cleanbyte. Khi một hàm giống như tự do được gọi, chúng được ghi đè bằng pymem_deadbyte, để bắt tham chiếu đến bộ nhớ tự do. Khi một hàm giống như realloc được gọi là 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.

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
84

Bản sao của pymem_forbiddenbyte. Được sử dụng để bắt quá mức và đọc.

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
85

Chỉ được sử dụng nếu macro

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
86 đượ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 cuộc gọi đến hàm giống như malloc hoặc giống như Realloc. Lớn

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
87. Nếu phát hiện ra bộ nhớ xấu của người Viking sau đó, số sê -ri sẽ đưa ra một cách tuyệt vời để đặt điểm dừng ở lần chạy tiếp theo, để nắm bắt ngay lập tức mà khối này được đưa ra. Hàm tĩnh bumpserialno () trong obmalloc.c là nơi duy nhất mà số sê -ri được tăng lên và tồn tại để bạn có thể đặt điểm dừng như vậy một cách dễ dàng.

Một hàm giống như realloc hoặc giống như tự do trước tiên kiểm tra xem các byte pymem_forbiddenbyte ở mỗi đầu có còn nguyên vẹn không. Nếu họ đã bị thay đổi, đầu ra chẩn đoán được ghi vào stderr và chương trình bị hủy bỏ thông qua py_fatalerror (). Chế độ thất bại chính khác đang gây ra lỗi bộ nhớ khi một 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ỉ. Nếu bạn nhận được một trình gỡ lỗi sau đó 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ớ không được sử dụng).

Đã thay đổi trong phiên bản 3.6: Hàm

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
44 hiện cũng hoạt động trên Python được biên dịch ở chế độ phát hành. Lỗi, các móc gỡ lỗi hiện sử dụng
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
67 để có được dấu vết trong đó một khối bộ nhớ được phân bổ. Các móc gỡ lỗi bây giờ cũng kiểm tra xem GIL có được giữ khi các chức năng của các miền
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
63 và
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
65 được gọi không.The
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
44 function now also works on Python compiled in release mode. On error, the debug hooks now use
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
67 to get the traceback where a memory block was allocated. The debug hooks now also check if the GIL is held when functions of
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
63 and
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
65 domains are called.

Thay đổi trong phiên bản 3.8: Các mẫu byte

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
92 (
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
56),
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
94 (
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
58) và
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
96 (
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
60) đã được thay thế bằng
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
55,
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
57 và
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
59Byte patterns
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
92 (
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
56),
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
94 (
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
58) and
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
96 (
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
60) have been replaced with
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
55,
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
57 and
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
59 to use the same values than Windows CRT debug malloc() and
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
2.

Người phân bổ pymalloc

Python có bộ phân bổ 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 tuổi thọ ngắn. Nó sử dụng các ánh xạ bộ nhớ được gọi là đấu trường trên mạng với kích thước cố định là 256 kib. Nó rơi trở lại

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
6 và
new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items
7 để phân bổ lớn hơn 512 byte.

Pymalloc là bộ phân bổ mặc định của các miền

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
65 (Xh:
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
9) và
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
63 (Xh:
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
7).default allocator of the
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
65 (ex:
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
9) and
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
63 (ex:
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
7) domains.

Trình phân bổ đấu trường sử dụng các chức năng sau:

  • alist = ['eggs', 2, 'juice']  # alist is reference to a new list
    blist = alist # blist is a reference; changing blist affects alist
    blist.append('coffee') # alist and blist both point to 
                           # ['eggs', 2, 'juice', 'coffee']
    
    09 và
    alist = ['eggs', 2, 'juice']  # alist is reference to a new list
    blist = alist # blist is a reference; changing blist affects alist
    blist.append('coffee') # alist and blist both point to 
                           # ['eggs', 2, 'juice', 'coffee']
    
    10 trên Windows,

  • alist = ['eggs', 2, 'juice']  # alist is reference to a new list
    blist = alist # blist is a reference; changing blist affects alist
    blist.append('coffee') # alist and blist both point to 
                           # ['eggs', 2, 'juice', 'coffee']
    
    11 và
    alist = ['eggs', 2, 'juice']  # alist is reference to a new list
    blist = alist # blist is a reference; changing blist affects alist
    blist.append('coffee') # alist and blist both point to 
                           # ['eggs', 2, 'juice', 'coffee']
    
    12 nếu có,

  • malloc()

    a = 2   # a is a reference to 2
    b = a   # b is a reference to 'a'
    b = 3   # b now points to 3, while 'a' continues to point to 2
    
    2 khác.

Bộ phân bổ này bị vô hiệu hóa nếu Python được cấu hình với tùy chọn

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
15. Nó cũng có thể bị vô hiệu hóa trong thời gian chạy bằng biến môi trường
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
3 (ví dụ:
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
17).
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
3 environment variable (ex:
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
17).

Tùy chỉnh Phân bổ đấu trường Pymalloc

Mới trong phiên bản 3.4.

TypePyObjectArenAllocator công trình được sử dụng để mô tả một trình phân bổ đấu trường. Cấu trúc có ba trường:PyObjectArenaAllocator

Structure used to describe an arena allocator. The structure has three fields:

Đồng ruộng

Nghĩa

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
22

Bối cảnh người dùng được thông qua như đối số đầu tiên

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
19

Phân bổ một đấu trường có kích thước byte

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
20

miễn phí một đấu trường

VoidPyObject_GetArenAallocator (PyObjectArenAallocator*Trình phân bổ)PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator)

Get the arena allocator.

VoidPyObject_setArenAallocator (PyObjectArenAallocator*Phân bổ) ¶ PyObject_SetArenaAllocator(PyObjectArenaAllocator*allocator)

Đặt trình phân bổ đấu trường.

tracemalloc c api¶

Mới trong phiên bản 3.7.

IntpyTracemalLoc_Track (unsignIntdomain, UINTPTR_TPTR, size_tsize) ¶Track một khối bộ nhớ được phân bổ trong mô -đun
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
67.
PyTraceMalloc_Track(unsigned intdomain, uintptr_tptr, size_tsize)

Track an allocated memory block in the

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
67 module.

Trả về

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
22 Khi thành công, trả lại
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
23 về lỗi (không phân bổ bộ nhớ để lưu trữ dấu vết). Trả về
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
24 Nếu Tracemalloc 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ó.

intpyTracemalLoc_untrack (unsignIntdomain, UINTPTR_TPTR) ¶untrack Một khối bộ nhớ được phân bổ trong mô -đun
a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
67. Không làm gì nếu khối không được theo dõi.
PyTraceMalloc_Untrack(unsignedintdomain, uintptr_tptr)

Untrack an allocated memory block in the

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2
67 module. Do nothing if the block was not tracked.

Trả về

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
24 Nếu Tracemalloc bị vô hiệu hóa, nếu không, hãy trả về
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
22.

Ví dụ;

Dưới đây là ví dụ từ phần tổng quan, viết lại để bộ đệm I/O được phân bổ từ đống python bằng cách sử dụng bộ chức năng đầu tiên:Overview, rewritten so that the I/O buffer is allocated from the Python heap by using the first function set:

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;

Cùng một mã sử dụng chức năng định hướng loạ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;

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 bộ. Thật vậy, cần phải sử dụng cùng một họ API bộ nhớ cho một khối bộ nhớ nhất định, do đó nguy cơ trộn các bộ phân phối khác nhau bị giảm xuống mức tối thiểu. Trình tự mã sau đây chứa hai lỗi, một trong số đó được dán nhãn là gây tử vong vì nó trộn hai bộ phân bổ khác nhau hoạt động trên các đố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ừ đống Python, các đối tượng trong Python được phân bổ và phát hành với

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
28,
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
29 và
alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']
30.

Chúng sẽ được giải thích trong chương tiếp theo về việc xác định và thực hiện các loại đối tượng mới trong C.

Python có cho phép phân bổ bộ nhớ động không?

Như chúng ta đã biết, Python sử dụng phân bổ bộ nhớ động được quản lý bởi cấu trúc dữ liệu HEAP. Bộ nhớ chứa các đối tượng và các cấu trúc dữ liệu khác sẽ được sử dụng trong chương trình. Trình quản lý bộ nhớ Python quản lý việc phân bổ hoặc phân bổ không gian bộ nhớ heap thông qua các hàm API.Python uses the dynamic memory allocation which is managed by the Heap data structure. Memory Heap holds the objects and other data structures that will be used in the program. Python memory manager manages the allocation or de-allocation of the heap memory space through the API functions.

Python có phân bổ bộ nhớ tự động không?

Lập trình viên phải phân bổ thủ công bộ nhớ trước khi chương trình có thể sử dụng và phát hành nó khi chương trình không còn cần nó nữa. Trong Python, quản lý bộ nhớ là tự động! Python tự động xử lý việc phân bổ và giải quyết bộ nhớ.In Python, memory management is automatic! Python automatically handles the allocation and deallocation of memory.

Python sử dụng phân bổ bộ nhớ tĩnh hoặc động?

Một lợi thế của phân bổ bộ nhớ động trong Python là chúng ta không cần phải lo lắng về việc chúng ta cần bao nhiêu bộ nhớ cho chương trình của mình trước đó.Một lợi thế khác là thao tác cấu trúc dữ liệu có thể được thực hiện tự do mà không phải lo lắng về nhu cầu phân bổ bộ nhớ cao hơn nếu cấu trúc dữ liệu mở rộng.dynamic memory allocation in Python is that we do not need to worry about how much memory we need for our program beforehand. Another advantage is that data structure manipulation can be done freely without having to worry about a need for higher memory allocation if the data structure expands.

Python có thể thao túng bộ nhớ?

Python tối ưu hóa việc sử dụng bộ nhớ bằng cách phân bổ cùng một tham chiếu đối tượng cho một biến mới nếu đối tượng đã tồn tại với cùng một giá trị.Đó là lý do tại sao Python được gọi là bộ nhớ hiệu quả hơn.. That is why python is called more memory efficient.