2010-09-24 4 views
8

J'écris un programme (un démonstrateur de théorèmes), dont l'exigence de mémoire est "autant que possible, s'il vous plaît"; c'est-à-dire, il peut toujours faire mieux en utilisant plus de mémoire, à des fins pratiques sans limite supérieure, donc ce qu'il faut réellement faire est d'utiliser autant de mémoire que disponible, ni plus, ni moins. Je peux comprendre comment classer les données par ordre de priorité pour supprimer les données les moins coûteuses lorsque la mémoire est insuffisante; le problème que j'essaie de résoudre est comment savoir quand cela se produit.Garder l'utilisation de la mémoire dans les limites de la quantité disponible

Idéalement je voudrais un appel système qui retourne "combien de mémoire il reste" ou "avons-nous encore de la mémoire?"; pour autant que je peux dire, aucune telle chose n'existe?

Bien sûr, malloc peut signaler un manque de mémoire en retournant 0 et new peut appeler un gestionnaire; ce ne sont pas des signaux idéaux, mais ce serait mieux que rien. Un problème, cependant, est que je veux vraiment savoir quand la mémoire physique est épuisée, de sorte que je peux éviter d'aller profondément dans l'échange et de faire ainsi tout s'arrêter; Je ne pense pas qu'il y ait moyen de se demander "devons-nous encore échanger?" ou dire au système d'exploitation "ne pas échanger sur mon compte, juste échouer mes demandes s'il s'agit de cela"?

Une autre approche consisterait à déterminer la quantité de RAM dans la machine et à surveiller la quantité de mémoire utilisée actuellement par le programme. Pour autant que je sache, il n'y a généralement aucun moyen de dire le premier? J'ai aussi l'impression qu'il n'y a pas de moyen fiable de dire à ce dernier sauf en encapsulant malloc/free avec une fonction bookkeeper (ce qui est alors plus problématique en C++).

Y a-t-il des approches qui me manquent?

L'idéal serait une solution portable, mais je soupçonne que cela n'arrivera pas. A défaut, une solution qui fonctionne sur Windows et une autre qui fonctionne sur Unix serait bien. A défaut, je pourrais me débrouiller avec une solution qui fonctionne sur Windows et une autre qui fonctionne sous Linux.

+0

Eh bien, tout ce que je peux dire à coup sûr, c'est que vous ne trouverez pas de solution portable. Oh, et que ce n'est pas la tâche la plus facile. – sbi

+1

Sur Linux: http://linux.die.net/man/2/getrusage peut-être? Sous Windows: GetProcessMemoryInfo peut-être? –

Répondre

6

Je pense que la manière la plus utile et la plus flexible d'utiliser toute la mémoire disponible est de laisser l'utilisateur spécifier la quantité de mémoire à utiliser. Laisser l'utilisateur l'écrire dans un fichier de configuration ou via une interface, puis créer un allocateur (ou quelque chose de similaire) qui ne fournira pas plus que cette mémoire. De cette façon, vous n'avez pas besoin de trouver des statistiques sur l'ordinateur actuel car cela sera toujours biaisé par le fait que le système d'exploitation pourrait également exécuter d'autres programmes. Ne parlez même pas de la façon dont le système d'exploitation va gérer le cache, les différences entre l'espace d'adressage de 32 et 64 bits limitent vos allocations, etc.En fin de compte, l'intelligence humaine (en supposant que l'utilisateur soit informé du contexte d'utilisation) est moins coûteuse à mettre en œuvre lorsqu'elle est fournie par l'utilisateur.

+0

C'est la bonne façon d'y aller - la pression de la mémoire pourrait bien être causée par d'autres applications en cours d'exécution, de toute façon. – caf

1

La meilleure solution que je puisse envisager est d'interroger le nombre de défauts de page qui se sont produits, par exemple, à la dernière seconde. S'il y a beaucoup de permutation, vous devriez probablement libérer de la mémoire, et sinon, vous pouvez essayer d'allouer plus de mémoire.

Sous Windows, WMI peut probablement vous fournir des statistiques que vous pouvez utiliser.

Mais c'est un problème difficile, car il n'y a pas de limite stricte que vous pouvez demander à l'OS et ensuite rester en dessous. Vous pouvez continuer à allouer de la mémoire bien au-delà du point où vous n'avez plus de mémoire physique, ce qui signifie simplement que vous allez paralyser votre processus avec un échange excessif.

Donc, le mieux que vous pouvez vraiment faire est une sorte d'approximation.

0

Vous pouvez continuer à allouer de la mémoire au-delà du point où cela est utile, c'est-à-dire ce qui nécessite un échange de l'OS ou un transfert de pages importantes. Le problème est, il n'est pas nécessairement facile de dire où c'est. De plus, si votre tâche effectue des opérations d'E/S (significatives), vous devrez en conserver quelques-uns pour les tampons du système d'exploitation.

Je recommande juste d'examiner combien il y a dans la machine, puis d'allouer une quantité en fonction de cela (proportion, ou laisser un peu de libre etc.).

2

Compter sur malloc pour renvoyer 0 lorsqu'aucune mémoire n'est disponible peut provoquer des problèmes sous Linux, car Linux overcommits memory allocations. malloc retournera généralement un pointeur valide (sauf si le processus est en dehors de l'espace d'adressage virtuel), mais l'accès à la mémoire vers laquelle il pointe peut déclencher le "OOM killer", un mécanisme qui tue votre processus ou un autre processus sur le système. L'administrateur système peut tune this behavior.

Questions connexes