Linux nimmt als in Servern und eingebetteten Geräten weit verbreitetes Betriebssystem einen wachsenden Marktanteil ein. In diesen Szenarien ist die Speicherverwaltung von entscheidender Bedeutung, da sie sich insbesondere für Programmierer direkt auf die Leistung und Stabilität des Systems auswirkt. Für Programmierer, die leistungsstarke Anwendungen auf der Linux-Plattform entwickeln möchten, sind Kenntnisse in der Linux-Speicherverwaltung ein Muss. Heute stellen wir einen Artikel vor, den jeder Programmierer lesen sollte: Linux-Speicherverwaltung.
Was Sie über den Speicherteil wissen müssen:
Lassen Sie uns zunächst einige grundlegende Kenntnisse betrachten. Aus Sicht eines Prozesses ist der Speicher in zwei Teile unterteilt: Kernelmodus und Benutzermodus. Das klassische Verhältnis ist wie folgt:
Der Übergang vom Benutzermodus zum Kernelmodus erfolgt im Allgemeinen durch Systemaufrufe und Interrupts. Der Speicher im Benutzermodus ist für unterschiedliche Zwecke in verschiedene Bereiche unterteilt:
Natürlich wird der Kernel-Modus nicht wahllos verwendet, daher ist er wie folgt unterteilt:
Schauen wir uns genauer an, wie mit diesen Erinnerungen umgegangen wird.
Adresse
Der Zuordnungsprozess von Adressen innerhalb von Linux ist logische Adresse –> lineare Adresse –> physikalische Adresse ist die einfachste: ein digitales Signal, das im Adressbus übertragen wird, während lineare Adresse und logische Adresse eine Konvertierungsregel darstellen sind wie folgt:
Dieser Teil wird durch die MMU vervollständigt, die die Hauptregister CR0 und CR3 umfasst. Was in den Maschinenanweisungen erscheint, ist die logische Adresse, und die Regeln für die logische Adresse lauten wie folgt:
Die logische Adresse in Linux entspricht der linearen Adresse, was bedeutet, dass Inter die Dinge aus Kompatibilitätsgründen sehr kompliziert macht und Linux sie vereinfacht, um faul zu sein.
So verwalten Sie den Speicher
Wenn das System startet, erkennt es die Größe und den Zustand des Speichers. Bevor komplexe Strukturen erstellt werden, ist es notwendig, diese Speicher auf einfache Weise zu verwalten. Dabei handelt es sich lediglich um eine Bitmap, es gibt jedoch auch einige Optimierungen darin. Ideen.
Egal wie optimiert Bootmem ist, schließlich muss es beim Zuweisen von Speicher durchlaufen werden: Das Buddy-System kann intern einige freie Speicherfragmente mit einer Potenz von 2 speichern Wenn Sie 3 Seiten zuweisen möchten, gehen Sie zur 4-Seiten-Liste und wählen Sie eine aus, weisen Sie 3 zu und legen Sie dann die verbleibende 1 zurück. Der Vorgang der Speicherfreigabe ist genau der umgekehrte Vorgang. Verwenden Sie ein Bild, um es darzustellen:
Sie können sehen, dass 0, 4, 5, 6 und 7 alle verwendet werden, wenn 1 und 2 veröffentlicht werden.
static inline unsigned long __find_buddy_index(unsigned long page_idx, unsigned int order) { return page_idx ^ (1
Wie Sie dem obigen Code entnehmen können, sind 0 und 1 Freunde und 2 und 3 sind Freunde. Obwohl 1 und 2 benachbart sind, sind sie es nicht. Speicherfragmentierung ist der Feind des Systembetriebs. Der Buddy-Systemmechanismus kann die Fragmentierung bis zu einem gewissen Grad verhindern. Darüber hinaus können wir die Anzahl der freien Seiten in jeder Bestellung ermitteln.
Jedes Mal, wenn das Partnersystem Speicher zuweist, erfolgt dies in Seiteneinheiten (4 KB), aber die meisten Datenstrukturen, die beim Betrieb des Systems verwendet werden, sind offensichtlich nicht kosteneffizient, einem kleinen Objekt 4 KB zuzuweisen. Verwenden Sie Slab unter Linux, um die Zuordnung kleiner Objekte zu lösen:
Schneiden Sie beim Laufen etwas Speicher „im Großhandel“ an Ihren Kumpel, verarbeiten Sie ihn, schneiden Sie ihn in Stücke und „verkaufen“ Sie ihn in großen Mengen. Mit der weit verbreiteten Anwendung großer Multiprozessorsysteme und NUMA-Systeme hat Slab endlich seine Mängel aufgedeckt:
Um diese Probleme zu lösen, haben Experten Slub entwickelt: Die Seitenstruktur wird geändert, um den Overhead der Slab-Verwaltungsstruktur zu reduzieren, jede CPU verfügt über eine lokal aktive Slab (kmem_cache_cpu) usw. Für kleine eingebettete Systeme gibt es eine Slab-Simulationsschicht, die in solchen Systemen weitere Vorteile bietet.
小内存的问题算是解决了,但还有一个大内存的问题:用伙伴系统分配10 x 4KB的数据时,会去16 x 4KB的空闲列表里面去找(这样得到的物理内存是连续的),但很有可能系统里面有内存,但是伙伴系统分配不出来,因为他们被分割成小的片段。那么,vmalloc就是要用这些碎片来拼凑出一个大内存,相当于收集一些“边角料”,组装成一个成品后“出售”:
之前的内存都是直接映射的,第一次感觉到页式管理的存在:D 另外对于高端内存,提供了kmap方法为page分配一个线性地址。
进程由不同长度的段组成:代码段、动态库的代码、全局变量和动态产生数据的堆、栈等,在Linux中为每个进程管理了一套虚拟地址空间:
在我们写代码malloc完以后,并没有马上占用那么大的物理内存,而仅仅是维护上面的虚拟地址空间而已,只有在真正需要的时候才分配物理内存,这就是COW(COPY-ON-WRITE:写时复制)技术,而物理分配的过程就是最复杂的缺页异常处理环节了,下面来看!
缺页异常
在实际需要某个虚拟内存区域的数据之前,和物理内存之间的映射关系不会建立。如果进程访问的虚拟地址空间部分尚未与页帧关联,处理器自动引发一个缺页异常。在内核处理缺页异常时可以拿到的信息如下:
处理的流程如下:
发生缺页异常的时候,可能因为不常使用而被swap到磁盘上了,swap相关的命令如下:
swapon 开启swap swapoff 关闭swap /proc/sys/vm/swapiness 分值越大越积极使用swap,可以修改/etc/sysctl.conf中添加vm.swappiness=xx[1-100]来修改
如果内存是mmap映射到内存中的,那么在读、写对应内存的时候也会产生缺页异常。
在Linux中,内存管理是一个复杂的主题,但是如果程序员能够理解并充分利用它,他们可以极大地提高他们的程序的性能和可靠性。在本文中,我们介绍了Linux内存管理的基本知识、虚拟内存的概念、内存映射文件以及交换空间等。此外,我们还介绍了一些有助于程序员优化内存使用的技巧和工具。现在,不要再让程序的性能拖慢了你的项目,去掌握Linux内存管理吧!
Das obige ist der detaillierte Inhalt vonMeistern Sie die Linux-Speicherverwaltung und verbessern Sie die Leistung Ihres Programms!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!