La fragmentation de la mémoire est le même concept que la fragmentation du disque : il s'agit d'un gaspillage d'espace dû au fait que les zones utilisées ne sont pas suffisamment rapprochées les unes des autres.
Supposons, pour un simple exemple de jouet, que vous disposiez de dix octets de mémoire :
| | | | | | | | | | |
0 1 2 3 4 5 6 7 8 9
Maintenant, allouons trois blocs de trois octets, nommés A, B, et C :
| A | A | A | B | B | B | C | C | C | |
0 1 2 3 4 5 6 7 8 9
Maintenant, désallouez le bloc B :
| A | A | A | | | | C | C | C | |
0 1 2 3 4 5 6 7 8 9
Maintenant, que se passe-t-il si nous essayons d'allouer un bloc de quatre octets D ? Eh bien, nous avons 4 octets de mémoire libre, mais nous n'avons pas 4 octets de mémoire libre. contiguës octets de mémoire libre, donc nous ne pouvons pas allouer D ! C'est une utilisation inefficace de la mémoire, car nous aurions dû pouvoir stocker D, mais nous n'avons pas pu. Et nous ne pouvons pas déplacer C pour faire de la place, car il est très probable que certaines variables de notre programme pointent vers C, et nous ne pouvons pas trouver et changer automatiquement toutes ces valeurs.
Comment savez-vous que c'est un problème ? Eh bien, le plus grand signe est que la taille de la mémoire virtuelle de votre programme est considérablement plus grande que la quantité de mémoire que vous utilisez réellement. Dans un exemple concret, vous disposeriez de beaucoup plus de dix octets de mémoire, de sorte que D serait alloué à partir de l'octet 9, et que les octets 3 à 5 resteraient inutilisés, à moins que vous n'allouiez ultérieurement quelque chose de trois octets ou moins.
Dans cet exemple, 3 octets ne représentent pas un grand gaspillage, mais considérons un cas plus pathologique où deux allocations de quelques octets sont, par exemple, séparées de dix mégaoctets en mémoire, et où vous devez allouer un bloc de taille 10 mégaoctets + 1 octet. Pour ce faire, vous devez demander au système d'exploitation plus de dix mégaoctets de mémoire virtuelle supplémentaire, alors que vous n'êtes qu'à un octet près d'avoir déjà assez d'espace.
Comment l'éviter ? Les pires cas tendent à se produire lorsque vous créez et détruisez fréquemment de petits objets, car cela tend à produire un effet "fromage suisse" avec de nombreux petits objets séparés par de nombreux petits trous, rendant impossible l'allocation d'objets plus grands dans ces trous. Lorsque vous savez que vous allez faire cela, une stratégie efficace consiste à pré-allouer un grand bloc de mémoire comme pool pour vos petits objets, puis à gérer manuellement la création des petits objets dans ce bloc, plutôt que de laisser l'allocateur par défaut s'en charger.
En général, moins vous faites d'allocations, moins la mémoire risque d'être fragmentée. Cependant, la STL gère ce problème de manière assez efficace. Si vous avez une chaîne de caractères qui utilise la totalité de son allocation actuelle et que vous lui ajoutez un caractère, elle n'est pas simplement réallouée à sa longueur actuelle plus un. doubles sa longueur. Il s'agit d'une variante de la stratégie du "pool pour les petites allocations fréquentes". La chaîne s'empare d'une grande partie de la mémoire afin de pouvoir gérer efficacement les petites augmentations de taille répétées sans avoir à effectuer de petites réallocations répétées. En fait, tous les conteneurs STL font ce genre de choses, donc en général vous n'aurez pas à vous soucier de la fragmentation causée par les conteneurs STL à réallocation automatique.
Bien sûr, les conteneurs STL ne mettent pas la mémoire en commun. entre Par conséquent, si vous créez de nombreux petits conteneurs (plutôt que quelques conteneurs qui sont fréquemment redimensionnés), vous devrez peut-être vous préoccuper de la prévention de la fragmentation de la même manière que vous le feriez pour tout petit objet fréquemment créé, STL ou non.
2 votes
Beaucoup de bonnes réponses, merci à tous !
5 votes
Il y a déjà beaucoup de bonnes réponses, mais voici quelques images d'une application réelle (Firefox) où la fragmentation de la mémoire était un gros problème : blog.pavlov.net/2007/11/10/memory-fragmentation
2 votes
@MariusGedminas le lien ne fonctionne plus c'est pourquoi il est important de fournir un bref résumé avec le lien ou de répondre à la question avec un résumé avec le lien.
0 votes
Bien sûr, mais ça fait plus d'une demi-décennie.
5 votes
Vous trouverez ci-dessous l'emplacement mis à jour des liens postés par Marius : pavlovdotnet.wordpress.com/2007/11/10/memory-fragmentation
0 votes
Un exemple très intéressant du problème dans le monde réel (Elemental War of Magic) : youtu.be/_zD33Hrbo4Y