


Modèle de mémoire Linux : une compréhension plus approfondie de la gestion de la mémoire
Avez-vous déjà rencontré divers problèmes de mémoire dans les systèmes Linux ? Tels que les fuites de mémoire, la fragmentation de la mémoire, etc. Ces problèmes peuvent être résolus grâce à une compréhension approfondie du modèle de mémoire Linux.
1. Avant-propos
Le noyau Linux prend en charge trois modèles de mémoire, à savoir le modèle de mémoire plate, le modèle de mémoire discontinue et le modèle de mémoire clairsemée. Le modèle de mémoire fait en réalité référence à la répartition de la mémoire physique du point de vue du processeur et à la méthode utilisée pour gérer ces mémoires physiques dans le noyau Linux. De plus, il convient de noter que cet article se concentre principalement sur les systèmes à mémoire partagée, ce qui signifie que tous les processeurs partagent un espace d'adressage physique.
Le contenu de cet article est organisé comme suit : Afin d'analyser clairement le modèle de mémoire, nous décrivons quelques termes de base, qui se trouvent au chapitre 2. Le troisième chapitre explique les principes de fonctionnement des trois modèles de mémoire. Le dernier chapitre est l'analyse du code. Le code provient du noyau 4.4.6. Pour les codes liés à l'architecture, nous utilisons ARM64 pour l'analyse.
2. Termes liés au modèle de mémoire
1. Qu'est-ce que le cadre de page ?
L'une des fonctions les plus importantes du système d'exploitation est de gérer diverses ressources du système informatique. En tant que ressource la plus importante : la mémoire, nous devons la gérer. Dans le système d'exploitation Linux, la mémoire physique est gérée en fonction de la taille de la page. La taille spécifique de la page est liée au matériel et à la configuration du système Linux 4k est le paramètre le plus classique. Par conséquent, pour la mémoire physique, nous la divisons en pages classées par taille de page. La zone mémoire de taille de page dans chaque mémoire physique est appelée cadre de page. Nous établissons une structure de données de page struct pour chaque cadre de page physique afin de suivre l'utilisation de chaque page physique : est-elle utilisée pour le segment de texte du noyau ? Ou s'agit-il d'un tableau de pages pour un processus ? Est-il utilisé pour divers caches de fichiers ou est-il dans un état libre...
Chaque cadre de page a une structure de données de page correspondante. Le système définit les macros page_to_pfn et pfn_to_page pour convertir entre le numéro de cadre de page et la structure de données de page. La méthode de conversion spécifique est liée au module de mémoire. , les trois modèles de mémoire du noyau Linux sont décrits en détail.
2. Qu'est-ce que le PFN ?
Pour un système informatique, l'intégralité de son espace d'adressage physique doit être un espace d'adressage commençant à 0 et se terminant par l'espace physique maximum que le système réel peut prendre en charge. Dans le système ARM, en supposant que l'adresse physique est de 32 bits, alors l'espace d'adressage physique est de 4G. Dans le système ARM64, si le nombre de bits d'adresse physique pris en charge est de 48, alors l'espace d'adressage physique est de 256T. Bien sûr, en fait, tout un espace d'adressage physique aussi grand n'est pas utilisé pour la mémoire, certains appartiennent également à l'espace d'E/S (bien sûr, certaines arches de CPU ont leur propre espace d'adressage IO indépendant). Par conséquent, l'espace d'adressage physique occupé par la mémoire doit être un intervalle limité et il est impossible de couvrir la totalité de l'espace d'adressage physique. Cependant, maintenant que la mémoire devient de plus en plus grande, pour les systèmes 32 bits, l'espace d'adressage physique 4G ne peut plus répondre aux besoins en mémoire, il existe donc le concept de mémoire élevée, qui sera décrit en détail plus tard.
PFN est l'abréviation du numéro de cadre de page. Le soi-disant cadre de page fait référence à la mémoire physique. La mémoire physique est divisée en zones de taille de page et chaque page est numérotée. En supposant que la mémoire physique commence à l'adresse 0, alors le cadre de page avec PFN égal à 0 est la page qui commence à l'adresse 0 (adresse physique). En supposant que la mémoire physique commence à l'adresse x, le numéro de la première image de page est (x>>PAGE_SHIFT).
3. Qu'est-ce que NUMA ?
Il existe deux options lors de la conception d'une architecture de mémoire pour les systèmes multiprocesseurs : L'une est l'UMA (accès uniforme à la mémoire). Tous les processeurs du système partagent un espace mémoire physique unifié et cohérent, quel que soit le processeur qui initie l'accès à l'adresse mémoire. est le même. NUMA (Non-Uniform Memory Access) est différent de UMA. L'accès à une certaine adresse mémoire est lié à la position relative entre la mémoire et le processeur. Par exemple, pour un processeur sur un nœud, l'accès à la mémoire locale prend plus de temps que l'accès à la mémoire distante.
3. Trois modèles de mémoire dans le noyau Linux
1. Qu'est-ce que le modèle de mémoire FLAT ?
Si du point de vue d'un processeur du système, lorsqu'il accède à la mémoire physique, l'espace d'adressage physique est un espace d'adressage continu sans trous, alors le modèle de mémoire de ce système informatique est une mémoire plate. Dans ce modèle de mémoire, la gestion de la mémoire physique est relativement simple. Chaque cadre de page physique aura une structure de données de page pour l'abstraire. Par conséquent, il existe un tableau de pages de structure (mem_map) dans le système, et chaque entrée du tableau pointe vers. une page physique réelle (cadre de page). Dans le cas d'une mémoire plate, la relation entre PFN (page frame number) et l'index du tableau mem_map est linéaire (il y a un décalage fixe, si l'adresse physique correspondant à la mémoire est égale à 0, alors PFN est l'index du tableau). Par conséquent, il est très simple de passer de PFN à la structure de données de page correspondante, et vice versa. Pour plus de détails, veuillez vous référer aux définitions de page_to_pfn et pfn_to_page. De plus, pour le modèle de mémoire plate, il n'y a qu'un seul nœud (struct pglist_data) (afin d'utiliser le même mécanisme que le modèle de mémoire discontinue). L'image ci-dessous décrit la situation de mémoire plate :

Il convient de souligner que la mémoire occupée par struct page est dans la plage directement mappée, le système d'exploitation n'a donc pas besoin de créer une table de pages pour celle-ci.
2. Qu'est-ce que le modèle de mémoire discontinue ?
Si l'espace d'adressage du processeur présente des trous et est discontinu lors de l'accès à la mémoire physique, alors le modèle de mémoire de ce système informatique est une mémoire discontinue. De manière générale, le modèle de mémoire d'un système informatique basé sur NUMA est la mémoire discontinue. Cependant, les deux concepts sont en réalité différents. NUMA met l'accent sur la relation de position entre la mémoire et le processeur, qui n'a rien à voir avec le modèle de mémoire. Cependant, comme la mémoire et le processeur sur le même nœud ont une relation de couplage plus étroite (accès plus rapide), plusieurs nœuds sont nécessaires pour la gérer. La mémoire discontinue est essentiellement une extension du modèle de mémoire à mémoire plate. La majeure partie de l'espace d'adressage de la mémoire physique entière est une grande partie de la mémoire, avec quelques trous au milieu. Chaque partie de l'espace d'adressage de la mémoire appartient à un nœud (le cas échéant). est limité à un. En interne, le modèle de mémoire du nœud est une mémoire plate). L'image ci-dessous décrit la situation de la mémoire discontinue :

Par conséquent, sous ce modèle de mémoire, il existe plusieurs données de nœuds (struct pglist_data), et la définition de macro NODE_DATA peut obtenir la structure pglist_data du nœud spécifié. Cependant, la mémoire physique gérée par chaque nœud est stockée dans le membre node_mem_map de la structure de données struct pglist_data (le concept est similaire à mem_map en mémoire plate). À ce stade, la conversion de PFN en une page de structure spécifique sera un peu plus compliquée. Nous devons d'abord obtenir l'ID de nœud de PFN, puis trouver la structure de données pglist_data correspondante basée sur cet ID, puis trouver le tableau de pages correspondant. La méthode suivante est une mémoire plate similaire.
3. Qu'est-ce que le modèle de mémoire clairsemée ?
Le modèle de mémoire est également un processus évolutif. Au début, la mémoire plate était utilisée pour abstraire un espace d'adressage mémoire continu (mem_maps[]). Après l'émergence de NUMA, l'ensemble de l'espace mémoire discontinu était divisé en plusieurs nœuds, et chaque nœud. Il s'agit d'un espace d'adressage mémoire continu, c'est-à-dire que l'unique mem_maps[] d'origine est devenu plusieurs mem_maps[]. Tout semble parfait, mais l'émergence du hotplug de mémoire rend la conception originale parfaite imparfaite, car même mem_maps[] dans un nœud peut être discontinu. En fait, après l'émergence de la mémoire fragmentée, le modèle de mémoire discontinue n'est plus aussi important. Il va de soi que la mémoire fragmentée peut éventuellement remplacer la mémoire discontinue. Ce processus de remplacement est encore en cours. Le noyau 4.4 dispose encore de trois modèles de mémoire. choisissez parmi.
Pourquoi dit-on que la mémoire clairsemée peut éventuellement remplacer la mémoire discontinue ? En fait, dans le modèle de mémoire clairsemée, l'espace d'adressage continu est divisé en sections selon SECTION (par exemple, 1G), et chaque section est connectée à chaud. Par conséquent, sous la mémoire clairsemée, l'espace d'adressage mémoire peut être divisé en plusieurs. sections détaillées. , prend en charge une mémoire discontinue plus discrète. De plus, avant l'apparition de la mémoire clairsemée, NUMA et mémoire discontinue étaient toujours dans une relation confuse : NUMA ne stipulait pas la continuité de sa mémoire, et le système de mémoire discontinue n'était pas nécessairement un système NUMA, mais ces deux configurations sont toutes multi- nœud. Avec la mémoire clairsemée, nous pouvons enfin séparer le concept de continuité de mémoire de NUMA : un système NUMA peut être une mémoire plate ou une mémoire clairsemée, et un système de mémoire clairsemée peut être NUMA ou UMA.
L'image ci-dessous illustre comment la mémoire clairsemée gère les cadres de page (SPARSEMEM_EXTREME est configuré) :

(Remarque : un pointeur mem_section dans l'image ci-dessus doit pointer vers une page, et il y a plusieurs unités de données struct mem_section dans une page)
L'ensemble de l'espace d'adressage physique continu est découpé section par section. À l'intérieur de chaque section, sa mémoire est continue (c'est-à-dire qu'elle est conforme aux caractéristiques de la mémoire plate. Par conséquent, le tableau de pages de mem_map est attaché à la structure de section (). struct mem_section) Au lieu de la structure des nœuds (struct pglist_data). Bien entendu, quel que soit le modèle de mémoire utilisé, la correspondance entre PFN et page doit être traitée. Cependant, la mémoire clairsemée a une notion supplémentaire de section, effectuant la conversion en PFNSectionpage.
Voyons d'abord comment convertir un PFN en structure de page : un tableau de pointeurs mem_section est défini statiquement dans le noyau. Une section comprend souvent plusieurs pages, il est donc nécessaire de convertir le PFN en numéro de section par décalage vers la droite, en utilisant le numéro de section. Pour l'index, la structure de données de section correspondant au PFN peut être trouvée dans le tableau de pointeurs mem_section. Après avoir trouvé la section, vous pouvez trouver la structure de données de la page correspondante le long de sa section_mem_map. À propos, au début, la mémoire clairsemée utilisait un tableau memory_section unidimensionnel (pas un tableau de pointeurs). Cette implémentation gaspille beaucoup de mémoire pour les systèmes particulièrement clairsemés (CONFIG_SPARSEMEM_EXTREME). De plus, il est plus pratique de sauvegarder le pointeur pour la prise en charge du hotplug. Si le pointeur est égal à NULL, cela signifie que la section n'existe pas. L'image ci-dessus décrit la situation d'un tableau de pointeurs mem_section unidimensionnel (SPARSEMEM_EXTREME est configuré). Pour une configuration non-SPARSEMEM_EXTREME, le concept est similaire. Vous pouvez lire le code pour l'opération spécifique.
C'est un peu gênant de passer d'une page à un PFN. En fait, PFN est divisé en deux parties : une partie est l'index de la section, et l'autre partie est le décalage de la page dans la section. Nous devons d'abord obtenir l'index de section de la page, puis obtenir la section_mémoire correspondante. Connaître la section_mem_map signifie que la page est dans la section_mem_map, et nous connaissons également le décalage de la page dans la section. Enfin, nous pouvons synthétiser le PFN. . Pour la conversion d'une page en index de section, la mémoire clairsemée propose deux solutions. Regardons d'abord la solution classique, qui est enregistrée dans page->flags (SECTION_IN_PAGE_FLAGS est configuré). Le plus gros problème avec cette méthode est que le nombre de bits dans page->flags n'est pas nécessairement suffisant, car cet indicateur contient trop d'informations. Divers indicateurs de page, identifiants de nœuds et identifiants de zone ajoutent désormais un identifiant de section que les algorithmes ne peuvent pas atteindre. cohérence dans différentes architectures. Existe-t-il un algorithme universel ? Il s'agit de CONFIG_SPARSEMEM_VMEMMAP. Pour l'algorithme spécifique, veuillez vous référer à la figure ci-dessous :

(Il y a un problème avec l'image ci-dessus. vmemmap ne pointe vers le premier tableau de page de structure que lorsque PHYS_OFFSET est égal à 0. De manière générale, il devrait y avoir un décalage, mais je suis trop paresseux pour le changer, haha)
Pour le modèle de mémoire clairsemée classique, la mémoire occupée par le tableau de pages struct d'une section provient de la zone directement mappée. La table des pages est établie lors de l'initialisation, et le cadre de page est alloué, ce qui signifie que l'adresse virtuelle est allouée. Cependant, pour SPARSEMEM_VMEMMAP, l'adresse virtuelle est allouée depuis le début. Il s'agit d'un espace d'adressage virtuel continu à partir de vmemmap. Chaque page a une page de structure correspondante. Bien entendu, il n'y a qu'une adresse virtuelle et aucune adresse physique. Par conséquent, lorsqu'une section est découverte, l'adresse virtuelle de la page de structure correspondante peut être trouvée immédiatement. Bien entendu, il est également nécessaire d'attribuer un cadre de page physique, puis d'établir une table de pages. Par conséquent, pour ce type de mémoire clairsemée, la surcharge sera légèrement plus importante (un processus supplémentaire d'établissement du mappage).
4. Analyse du code
Notre analyse de code est principalement effectuée via include/asm-generic/memory_model.h.
1. mémoire plate. Le code est le suivant :
«
\#define __pfn_to_page(pfn) (mem_map + ((pfn) - ARCH_PFN_OFFSET)) \#define __page_to_pfn(page) ((unsigned long)((page) - mem_map) + ARCH_PFN_OFFSET)”
Il ressort du code que l'index PFN et le tableau de pages struct (mem_map) sont liés de manière linéaire, et il existe un décalage fixe appelé ARCH_PFN_OFFSET. Ce décalage est lié à l'architecture estimée. Pour ARM64, elle est définie dans le fichier arch/arm/include/asm/memory.h. Bien entendu, cette définition est liée à l'espace d'adressage physique occupé par la mémoire (c'est-à-dire liée à la définition de PHYS_OFFSET).
2. Modèle de mémoire discontinue. Le code est le suivant :
“
\#define __pfn_to_page(pfn) \ ({ unsigned long __pfn = (pfn); \ unsigned long __nid = arch_pfn_to_nid(__pfn); \ NODE_DATA(__nid)->node_mem_map + arch_local_page_offset(__pfn, __nid);\ }) \#define __page_to_pfn(pg) \ ({ const struct page *__pg = (pg); \ struct pglist_data *__pgdat = NODE_DATA(page_to_nid(__pg)); \ (unsigned long)(__pg - __pgdat->node_mem_map) + \ __pgdat->node_start_pfn; \ })”
Discontiguous Memory Model需要获取node id,只要找到node id,一切都好办了,比对flat memory model进行就OK了。因此对于__pfn_to_page的定义,可以首先通过arch_pfn_to_nid将PFN转换成node id,通过NODE_DATA宏定义可以找到该node对应的pglist_data数据结构,该数据结构的node_start_pfn记录了该node的第一个page frame number,因此,也就可以得到其对应struct page在node_mem_map的偏移。__page_to_pfn类似,大家可以自己分析。
3、Sparse Memory Model。经典算法的代码我们就不看了,一起看看配置了SPARSEMEM_VMEMMAP的代码,如下:
“
\#define __pfn_to_page(pfn) (vmemmap + (pfn)) \#define __page_to_pfn(page) (unsigned long)((page) - vmemmap)”
简单而清晰,PFN就是vmemmap这个struct page数组的index啊。对于ARM64而言,vmemmap定义如下:
“
\#define vmemmap ((struct page *)VMEMMAP_START - \ SECTION_ALIGN_DOWN(memstart_addr >> PAGE_SHIFT))”
毫无疑问,我们需要在虚拟地址空间中分配一段地址来安放struct page数组(该数组包含了所有物理内存跨度空间page),也就是VMEMMAP_START的定义。
总之,Linux内存模型是一个非常重要的概念,可以帮助你更好地理解Linux系统中的内存管理。如果你想了解更多关于这个概念的信息,可以查看本文提供的参考资料。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

LinuxOffersMoreDevenertools, en particulier open-SourceandCommand-basé, tandis que Windowshashasimproved avec les érootes, la ligne de commande, la lignée de commandement, laystemoptimisation, le fait de faire de la ligne de commandement, de la ligne de commandement, de la ligne de commande, de la systemoptimisation,

Cet article explore les meilleures distributions Linux offrant une expérience de bureau de type Windows. Le passage de Windows, en particulier de Windows 10 (publié le 29 juillet 2015) et de son successeur Windows 11 (5 octobre 2021), est souvent considéré par les utilisateurs

En tant qu'administrateur avec plus de dix ans d'expérience dans la gestion de Linux, ma responsabilité principale est toujours la gestion de la sécurité des serveurs Linux. Les pare-feu jouent un rôle essentiel dans la protection des systèmes Linux et de la sécurité du réseau. Ils sont comme des agents de sécurité entre les réseaux internes et externes, contrôlant et gérant dans et hors du trafic réseau en fonction d'un ensemble de règles prédéfinies. Ces règles de pare-feu permettent des connexions légales et bloquent les connexions non spécifiées. Il existe de nombreuses applications de pare-feu open source disponibles ces jours-ci, et le choix de la bonne application pour vos besoins peut être difficile. Dans cet article, nous explorerons les dix pare-feu open source les plus populaires qui peuvent aider à protéger vos serveurs Linux en 2024. Iptables /

Cet article explore d'autres commandes et programmes Linux basés sur X précieux, en développant notre couverture précédente des commandes Linux basées sur l'interface graphique. xwininfo: dévoiler les détails de la fenêtre Xwininfo est un utilitaire de ligne de commande fournissant des informations complètes

Netdata: A powerful tool to easily monitor the performance of MySQL databases on Linux systems NetData est une application de performance et de surveillance de la santé gratuite et open source en temps réel adaptée aux systèmes de type UNIX tels que Linux, FreeBSD et MacOS. It collects and visualizes various metrics, allowing you to monitor the system's operation in real time. NetData prend en charge une variété de plug-ins qui peuvent surveiller l'état du système actuel, exécuter les applications et les services, tels que les serveurs de base de données MySQL, etc. This article will guide you on how to monitor the performance of MySQL database servers using Netdata on RHEL-based distributions. After reading, you will be able to go through Netdata's web interface,

Commande Linux Diff3: un outil puissant pour comparer et fusion trois fichiers La commande DIFF3 est un outil puissant de Linux qui compare trois fichiers et affiche leurs différences. Ceci est très utile pour les programmeurs et les administrateurs système qui s'occupent souvent de plusieurs versions du même fichier, ayant besoin de fusionner ces versions ou d'identifier les changements entre différentes versions. Cet article présentera l'utilisation de base de la commande Diff3, des options communes et quelques exemples pour vous aider à comprendre comment il fonctionne dans Linux. Quelle est la commande Diff3? Diff3 est un outil pour comparer trois fichiers ligne par ligne, qui reconnaît les différences et les affiche dans un format facile à comprendre. Il peut être utilisé pour: Trouvez trois articles

Ce guide fournit une procédure pas à pas complète pour installer le logiciel de gestion SMS open source, PlaySMS, sur un serveur Linux. C'est un outil puissant pour la gestion efficace de la communication SMS. Exigences du système: Avant de commencer, assurez-vous votre S

Clémentine: Votre lecteur de musique polyvalent et convivial pour Linux, MacOS et Windows Clementine est un lecteur de musique moderne et léger conçu pour la facilité d'utilisation, en particulier sur les systèmes Linux. Inspiré par Amarok, Clementine dépasse son prédécesseur


Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

SublimeText3 Linux nouvelle version
Dernière version de SublimeText3 Linux

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Version Mac de WebStorm
Outils de développement JavaScript utiles

MinGW - GNU minimaliste pour Windows
Ce projet est en cours de migration vers osdn.net/projects/mingw, vous pouvez continuer à nous suivre là-bas. MinGW : un port Windows natif de GNU Compiler Collection (GCC), des bibliothèques d'importation et des fichiers d'en-tête librement distribuables pour la création d'applications Windows natives ; inclut des extensions du runtime MSVC pour prendre en charge la fonctionnalité C99. Tous les logiciels MinGW peuvent fonctionner sur les plates-formes Windows 64 bits.

Dreamweaver CS6
Outils de développement Web visuel
