2017-02-23 2 views
2

Les systèmes d'exploitation comme Linux fonctionnent sur le principe de la copie à l'écriture, donc même si vous allouez un tableau de 100 Go, mais n'utilisez que 10 Go, vous n'utiliserez que 10 Go de mémoire. Alors, quel serait l'inconvénient de créer un tel tableau? Cependant, je peux voir un avantage, à savoir que vous n'aurez pas à vous soucier de l'utilisation d'un tableau dynamique, ce qui entraînerait le coût des réaffectations.Quel serait l'inconvénient de créer un tableau de très grande taille sur les systèmes 64 bits?

+0

Je ne suis pas sûr que la copie sur écriture est pertinente à votre capacité à allouer 100 Go. –

+0

Inconvénient possible: faire mourir OOM sans pouvoir déboguer la cause? –

+0

Pourquoi pas? Fondamentalement, lorsque vous allouez 100 Go, vous occupez uniquement un espace d'adressage, ce qui est suffisant sur un système 64 bits. Copy-on-write signifie que vous n'utilisez pas réellement la mémoire tant que vous ne l'avez pas touchée. – pythonic

Répondre

3

L'inconvénient principal est que, ce faisant, vous faites une hypothèse forte sur la façon dont fonctionnent exactement les allocateurs de bibliothèque standard et les allocateurs Linux sous-jacents. En fait, les allocateurs et le système sous-jacent ne fonctionnent pas toujours comme vous le mentionnez.

Maintenant, vous avez mentionné « copie à l'écriture », mais ce que vous probablement allusion vraiment est la combinaison de la population page paresseux et overcommit. Selon la configuration, cela signifie que la mémoire que vous allouez mais que vous ne touchez pas peut ne pas être prise en compte dans les limites de la mémoire et ne pas occuper la mémoire physique.

Le problème est que cela peut souvent ne pas fonctionner. Par exemple:

  • De nombreux allocataires ont des modes où ils touchent la mémoire allouée, par exemple, en mode débogage pour le remplir avec un modèle connu pour aider à diagnostiquer les références à la mémoire non initialisée. La plupart des allocateurs touchent au moins quelques octets avant votre région allouée pour stocker les métadonnées pouvant être utilisées lors de la désallocation. Donc, vous faites une hypothèse forte sur le comportement de l'allocateur qui est susceptible de se casser.
  • Le comportement de dépassement de capacité Linux est totally configurable. En pratique, de nombreux utilisateurs Linux côté serveur vont le désactiver afin de réduire l'incertitude et les problèmes irrécupérables liés au tueur OOM. Donc, votre affirmation selon laquelle Linux se comporte paresseusement n'est vraie que pour certaines configurations trop rapides et fausse pour d'autres.
  • Vous pouvez supposer que la mémoire est en cours d'exécution dans des blocs 4K et ajuster votre algorithme autour de cela. Cependant, les systèmes ont des tailles de page différentes: 16K et 64K ne sont pas rares en tant que tailles de page de base, et les systèmes Linux x86 par défaut ont transparent huge pages activé, donc vous pouvez réellement obtenir 2.048K pages sans le savoir! Dans ce cas, vous risquez de commettre presque tout le tableau, en fonction de votre modèle d'accès.
  • Comme mentionné dans les commentaires, le "mode de défaillance" pour ce type d'utilisation est assez médiocre. Vous pensez que vous n'utiliserez qu'une petite partie du tableau, mais si vous en utilisez plus que ce que le système peut gérer, au mieux, vous pourrez obtenir un signal à votre application sur un accès aléatoire à une nouvelle page, mais plus comme le tueur d'oom va juste tuer un autre processus aléatoire sur votre machine.

Ici je suppose que vous utilisez quelque chose comme malloc ou new d'affecter le tableau, puisque vous n'avez pas parlé directement mmap ing ou quoi que ce soit.

+0

J'ai impliqué mmap bien sûr – pythonic

+2

Non, vous n'avez pas. – BeeOnRope

2

Les systèmes d'exploitation réels ne permettent pas simplement à votre programme d'accéder à toute la mémoire disponible - ils imposent des quotas. Ainsi, un système d'exploitation 64 bits, fonctionnant sur du matériel avec assez de mémoire physique, refusera tout simplement d'allouer toute cette mémoire à n'importe quel programme. Cela est encore plus vrai si votre système d'exploitation est virtualisé (par exemple, certains hyperviseurs hébergent deux ou plusieurs systèmes d'exploitation sur la même plate-forme physique - l'hyperviseur impose des quotas pour chaque système d'exploitation hébergé et l'un impose des quotas pour votre programme).

Tentative d'allouer une grande quantité de mémoire est donc, en pratique, un moyen efficace de maximiser la probabilité que le système d'exploitation ne permettra pas à votre programme la mémoire dont il a besoin.

Alors, oui, il est possible pour un administrateur d'augmenter les quotas, qui a des conséquences aussi bien. Si vous n'avez pas d'accès administratif, vous devez convaincre un administrateur d'augmenter ces quotas (ce qui n'est pas forcément facile à moins que votre machine n'ait qu'un seul utilisateur). Un programme qui consomme une grande quantité de mémoire peut entraîner la perte de mémoire pour d'autres programmes - ce qui devient un problème si ces autres programmes sont nécessaires pour vous ou pour d'autres personnes. Dans les cas extrêmes, votre programme peut priver le système d'exploitation lui-même des ressources, ce qui entraîne un ralentissement de tous les programmes qu'il héberge et compromet la stabilité du système. Ce genre de préoccupations est pourquoi les systèmes appliquent des quotas en premier lieu - souvent par défaut.

Il y a aussi des problèmes qui peuvent survenir parce que les systèmes d'exploitation peuvent être configurés pour des engagements excédentaires. Autrement dit, lorsqu'un programme demande de la mémoire, le système d'exploitation indique au programme que l'allocation a réussi, même si le système d'exploitation ne l'a pas alloué. Par la suite, lorsque le programme utilise cette mémoire (généralement, écrit des données), le système d'exploitation doit soudainement rendre la mémoire disponible. Si le système d'exploitation ne peut pas le faire pour une raison quelconque, cela devient un problème pour le programme (qui croit avoir accès à la mémoire, mais le système d'exploitation empêche l'accès). Cela entraîne généralement une condition d'erreur affectant l'exécution du programme (et entraîne souvent la fin du programme). Alors que les problèmes associés à la sur-validation peuvent affecter n'importe quel programme, les chances sont nettement augmentées lorsque le programme alloue une grande quantité de mémoire.

+0

Pour être juste, l'utilisateur ne demande pas pourquoi il est mauvais d'utiliser une grande quantité de mémoire, mais si la stratégie d'allocation mais pas d'utilisation (donc pas de remplissage des pages) est raisonnable. La plupart des raisons ci-dessus ne s'appliquent pas à ce cas, car le processus n'utilise plus de mémoire physique ou de pages virtuelles mappées par rapport à l'alternative qui alloue moins. En particulier, les paramètres habituels 'ulimit' ne vont pas entrer ici, seulement' ulimit -v' fonctionnera et c'est assez problématique car cela ne compte pas. – BeeOnRope

+0

.... sauf que l'allocation d'un tableau de 100 Go et seulement l'utilisation de 10 Go de celui-ci (ce que l'OP a posé à propos de) serait encore valider les 100 Go. L'OP n'a pas posé de questions sur l'allocation clairsemée, mais seulement sur l'utilisation parcimonieuse (en utilisant 1 partie sur 10) d'un bloc alloué par le programme. – Peter

+0

En général, sur Linux, il ne commet pas les 100 Go. Les pages sont validées une par une (ou éventuellement dans de petits groupes avec des erreurs autour pour un mappage de fichier) lors du premier accès. C'est l'astuce qui vous permet d'allouer un tableau beaucoup plus grand que votre mémoire physique plus swap tant que vous n'y accédez pas beaucoup. – BeeOnRope