Python 的内存管理架构(Objects/obmalloc.c):
_____ ______ ______ ________
[ int ] [ dict ] [ list ] ... [ string ] Python core |
+3 | | |
_______________________________ | |
[ Python's object allocator ] | |
+2 | ####### Object memory ####### | |
______________________________________________________________ |
[ Python's raw memory allocator (PyMem_ API) ] |
+1 | | |
__________________________________________________________________
[ Underlying general-purpose allocator (ex: C library malloc) ]
0 | |
0. C语言库函数提供的接口
1. PyMem_*家族,是对 C中的 malloc、realloc和free 简单的封装,提供底层的控制接口。
2. PyObject_* 家族,高级的内存控制接口。
3. 对象类型相关的管理接口
PyMem_*
PyMem_家族:低级的内存分配接口(low-level memory allocation interfaces)
Python 对C中的 malloc、realloc和free 提供了简单的封装:
为什么要这么多次一举:
- 不同的C实现对于malloc(0)产生的结果有会所不同,而PyMem_MALLOC(0)会转成malloc(1).
- 不用的C实现的malloc与free混用会有潜在的问题。python提供封装可以避免这个问题。
- Python提供了宏和函数,但是宏无法避免这个问题,故编写扩展是应避免使用宏
源码:
Include/pymem.h #define PyMem_MALLOC(n) ((size_t)(n) > (size_t)PY_SSIZE_T_MAX ? NULL \ : malloc((n) ? (n) : 1)) #define PyMem_REALLOC(p, n) ((size_t)(n) > (size_t)PY_SSIZE_T_MAX ? NULL \ : realloc((p), (n) ? (n) : 1)) #define PyMem_FREE free Objects/object.c /* Python's malloc wrappers (see pymem.h) */ void * PyMem_Malloc(size_t nbytes) { return PyMem_MALLOC(nbytes); } ...
PyMem_New 和 PyMem_NEW
PyMem_Resize和 PyMem_RESIZE
它们可以感知类型的大小
#define PyMem_New(type, n) \ ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ ( (type *) PyMem_Malloc((n) * sizeof(type)) ) ) #define PyMem_Resize(p, type, n) \ ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) #define PyMem_Del PyMem_Free #define PyMem_DEL PyMem_FREE
PyObject_*
PyObject_*家族,是高级的内存控制接口(high-level object memory interfaces)。
注意
- 不要和PyMem_*家族混用!!
- 除非有特殊的内粗管理要求,否则应该坚持使用PyObject_*
源码
Include/objimpl.h #define PyObject_New(type, typeobj) \ ( (type *) _PyObject_New(typeobj) ) #define PyObject_NewVar(type, typeobj, n) \ ( (type *) _PyObject_NewVar((typeobj), (n)) ) Objects/object.c PyObject * _PyObject_New(PyTypeObject *tp) { PyObject *op; op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp)); if (op == NULL) return PyErr_NoMemory(); return PyObject_INIT(op, tp); } PyVarObject * _PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems) { PyVarObject *op; const size_t size = _PyObject_VAR_SIZE(tp, nitems); op = (PyVarObject *) PyObject_MALLOC(size); if (op == NULL) return (PyVarObject *)PyErr_NoMemory(); return PyObject_INIT_VAR(op, tp, nitems); }
它们执行两项操作:
- 分配内存:PyObject_MALLOC
- 部分初始化对象:PyObject_INIT和PyObject_INIT_VAR
初始化没什么好看到,但是这个MALLOC就有点复杂无比了...
PyObject_{Malloc、Free}
这个和PyMem_*中的3个可是大不一样了,复杂的厉害!
void * PyObject_Malloc(size_t nbytes) void * PyObject_Realloc(void *p, size_t nbytes) void PyObject_Free(void *p)
Python程序运行时频繁地需要创建和销毁小对象,为了避免大量的malloc和free操作,Python使用了内存池的技术。
- 一系列的 arena(每个管理256KB) 构成一个内存区域的链表
- 每个 arena 有很多个 pool(每个4KB) 构成
- 每次内存的申请释放将在一个 pool 内进行
单次申请内存块
当申请大小在 1~256 字节之间的内存时,使用内存池(申请0或257字节以上时,将退而使用我们前面提到的PyMem_Malloc)。
每次申请时,实际分配的空间将按照某个字节数对齐,下表中为8字节(比如PyObject_Malloc(20)字节将分配24字节)。
Request in bytes Size of allocated block Size class idx
----------------------------------------------------------------
1-8 8 0
9-16 16 1
17-24 24 2
25-32 32 3
33-40 40 4
... ... ...
241-248 248 30
249-256 256 31
0, 257 and up: routed to the underlying allocator.
这些参数由一些宏进行控制:
#define ALIGNMENT 8 /* must be 2^N */ /* Return the number of bytes in size class I, as a uint. */ #define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT) #define SMALL_REQUEST_THRESHOLD 256
pool
每次申请的内存块都是需要在 pool 中进行分配,一个pool的大小是 4k。由下列宏进行控制:
#define SYSTEM_PAGE_SIZE (4 * 1024)
#define POOL_SIZE SYSTEM_PAGE_SIZE /* must be 2^N */
每个pool的头部的定义如下:
struct pool_header { union { block *_padding; uint count; } ref; /* number of allocated blocks */ block *freeblock; /* pool's free list head */ struct pool_header *nextpool; /* next pool of this size class */ struct pool_header *prevpool; /* previous pool "" */ uint arenaindex; /* index into arenas of base adr */ uint szidx; /* block size class index */ uint nextoffset; /* bytes to virgin block */ uint maxnextoffset; /* largest valid nextoffset */ };
注意,其中有个成员 szidx,对应前面列表中最后一列的 Size class idx。这也说明一个问题:每个 pool 只能分配固定大小的内存块(比如,只分配16字节的块,或者只分配24字节的块...)。
要能分配前面列表中各种大小的内存块,必须有多个 pool。同一大小的pool分配完毕,也需要新的pool。多个pool依次构成一个链表
arena
多个pool对象使用被称为 arena 的东西进行管理。
struct arena_object { uptr address; block* pool_address; uint nfreepools; uint ntotalpools; struct pool_header* freepools; struct arena_object* nextarena; struct arena_object* prevarena; };
arean控制的内存的大小由下列宏控制:
#define ARENA_SIZE (256 << 10) /* 256KB */
一系列的 arena 构成一个链表。
引用计数与垃圾收集
Python中多数对象的生命周期是通过引用计数来控制的,从而实现了内存的动态管理。
但是引用计数有一个致命的问题:循环引用!
为了打破循环引用,Python引入了垃圾收集技术。

Python und C haben jeweils ihre eigenen Vorteile, und die Wahl sollte auf Projektanforderungen beruhen. 1) Python ist aufgrund seiner prägnanten Syntax und der dynamischen Typisierung für die schnelle Entwicklung und Datenverarbeitung geeignet. 2) C ist aufgrund seiner statischen Tipp- und manuellen Speicherverwaltung für hohe Leistung und Systemprogrammierung geeignet.

Die Auswahl von Python oder C hängt von den Projektanforderungen ab: 1) Wenn Sie eine schnelle Entwicklung, Datenverarbeitung und Prototypdesign benötigen, wählen Sie Python. 2) Wenn Sie eine hohe Leistung, eine geringe Latenz und eine schließende Hardwarekontrolle benötigen, wählen Sie C.

Indem Sie täglich 2 Stunden Python -Lernen investieren, können Sie Ihre Programmierkenntnisse effektiv verbessern. 1. Lernen Sie neues Wissen: Lesen Sie Dokumente oder sehen Sie sich Tutorials an. 2. Üben: Schreiben Sie Code und vollständige Übungen. 3. Überprüfung: Konsolidieren Sie den Inhalt, den Sie gelernt haben. 4. Projektpraxis: Wenden Sie an, was Sie in den tatsächlichen Projekten gelernt haben. Ein solcher strukturierter Lernplan kann Ihnen helfen, Python systematisch zu meistern und Karriereziele zu erreichen.

Zu den Methoden zum effizienten Erlernen von Python innerhalb von zwei Stunden gehören: 1. Überprüfen Sie das Grundkenntnis und stellen Sie sicher, dass Sie mit der Python -Installation und der grundlegenden Syntax vertraut sind. 2. Verstehen Sie die Kernkonzepte von Python wie Variablen, Listen, Funktionen usw.; 3.. Master Basic und Advanced Nutzung unter Verwendung von Beispielen; 4.. Lernen Sie gemeinsame Fehler und Debugging -Techniken; 5. Wenden Sie Leistungsoptimierung und Best Practices an, z. B. die Verwendung von Listenfunktionen und dem Befolgen des Pep8 -Stilhandbuchs.

Python ist für Anfänger und Datenwissenschaften geeignet und C für Systemprogramme und Spieleentwicklung geeignet. 1. Python ist einfach und einfach zu bedienen, geeignet für Datenwissenschaft und Webentwicklung. 2.C bietet eine hohe Leistung und Kontrolle, geeignet für Spieleentwicklung und Systemprogrammierung. Die Wahl sollte auf Projektbedürfnissen und persönlichen Interessen beruhen.

Python eignet sich besser für Datenwissenschaft und schnelle Entwicklung, während C besser für Hochleistungen und Systemprogramme geeignet ist. 1. Python -Syntax ist prägnant und leicht zu lernen, geeignet für die Datenverarbeitung und wissenschaftliches Computer. 2.C hat eine komplexe Syntax, aber eine hervorragende Leistung und wird häufig in der Spieleentwicklung und der Systemprogrammierung verwendet.

Es ist machbar, zwei Stunden am Tag zu investieren, um Python zu lernen. 1. Lernen Sie neues Wissen: Lernen Sie in einer Stunde neue Konzepte wie Listen und Wörterbücher. 2. Praxis und Übung: Verwenden Sie eine Stunde, um Programmierübungen durchzuführen, z. B. kleine Programme. Durch vernünftige Planung und Ausdauer können Sie die Kernkonzepte von Python in kurzer Zeit beherrschen.

Python ist leichter zu lernen und zu verwenden, während C leistungsfähiger, aber komplexer ist. 1. Python -Syntax ist prägnant und für Anfänger geeignet. Durch die dynamische Tippen und die automatische Speicherverwaltung können Sie die Verwendung einfach zu verwenden, kann jedoch zur Laufzeitfehler führen. 2.C bietet Steuerung und erweiterte Funktionen auf niedrigem Niveau, geeignet für Hochleistungsanwendungen, hat jedoch einen hohen Lernschwellenwert und erfordert manuellem Speicher und Typensicherheitsmanagement.


Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

DVWA
Damn Vulnerable Web App (DVWA) ist eine PHP/MySQL-Webanwendung, die sehr anfällig ist. Seine Hauptziele bestehen darin, Sicherheitsexperten dabei zu helfen, ihre Fähigkeiten und Tools in einem rechtlichen Umfeld zu testen, Webentwicklern dabei zu helfen, den Prozess der Sicherung von Webanwendungen besser zu verstehen, und Lehrern/Schülern dabei zu helfen, in einer Unterrichtsumgebung Webanwendungen zu lehren/lernen Sicherheit. Das Ziel von DVWA besteht darin, einige der häufigsten Web-Schwachstellen über eine einfache und unkomplizierte Benutzeroberfläche mit unterschiedlichen Schwierigkeitsgraden zu üben. Bitte beachten Sie, dass diese Software

mPDF
mPDF ist eine PHP-Bibliothek, die PDF-Dateien aus UTF-8-codiertem HTML generieren kann. Der ursprüngliche Autor, Ian Back, hat mPDF geschrieben, um PDF-Dateien „on the fly“ von seiner Website auszugeben und verschiedene Sprachen zu verarbeiten. Es ist langsamer und erzeugt bei der Verwendung von Unicode-Schriftarten größere Dateien als Originalskripte wie HTML2FPDF, unterstützt aber CSS-Stile usw. und verfügt über viele Verbesserungen. Unterstützt fast alle Sprachen, einschließlich RTL (Arabisch und Hebräisch) und CJK (Chinesisch, Japanisch und Koreanisch). Unterstützt verschachtelte Elemente auf Blockebene (wie P, DIV),

SublimeText3 Englische Version
Empfohlen: Win-Version, unterstützt Code-Eingabeaufforderungen!

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen