90 votes

Comment obtenir la mémoire disponible C++/g++ ?

Je veux allouer mes tampons en fonction de la mémoire disponible. Ainsi, lorsque j'effectue un traitement et que l'utilisation de la mémoire augmente, elle reste toujours dans les limites de la mémoire disponible. Existe-t-il un moyen d'obtenir la mémoire disponible (je ne sais pas si l'état de la mémoire virtuelle ou physique fera une différence ?) La méthode doit être indépendante de la plateforme car elle sera utilisée sous Windows, OS X, Linux et AIX. (Et si possible, je voudrais aussi allouer une partie de la mémoire disponible pour mon application, quelqu'un qui ne change pas pendant l'exécution).

Edit : Je l'ai fait avec une allocation de mémoire configurable. Je comprends que ce n'est pas une bonne idée, car la plupart des systèmes d'exploitation gèrent la mémoire pour nous, mais mon application était un framework ETL (destiné à être utilisé sur un serveur, mais qui était également utilisé sur un ordinateur de bureau comme un plugin pour Adobe Indesign). J'ai donc été confronté au problème suivant : au lieu d'utiliser le swap, Windows renvoyait une mauvaise allocation et d'autres applications commençaient à échouer. Et comme on m'a appris à éviter les pannes et ainsi de suite, j'essayais juste de me dégrader gracieusement.

13 votes

Il n'y a aucun intérêt à faire cela. Sur tous les systèmes d'exploitation modernes, la mémoire utilisée par une application n'affecte pas la mémoire disponible pour les autres applications, car elle est entièrement virtuelle. N'allouez que ce dont vous avez besoin.

9 votes

@LokiAstari : faux bien sûr. un système n'a qu'une quantité limitée qu'il peut allouer. J'ai choisi de ne pas avoir de fichiers de swap, donc mon système a 8GiB, après cela, les appels C++ à new lancez bad_alloc et d'autres applications échouent. Dans Linux et les Windows récents, il existe un tueur d'OOM qui choisit une application à tuer. Un virus pourrait allouer beaucoup de choses dans plusieurs processus et utiliser ce fait pour faire planter d'autres applications. Sans parler du fait que si vous avez un fichier de page, le système va se détruire et se figer jusqu'à devenir inutilisable. (En général, seul le WM meurt, mais sous Windows, il n'y a pas de Ctrl-Alt-F1).

1 votes

@v.oddou : Rien de tout cela n'est pertinent dans le contexte de la question. Mon commentaire est donc maintenu.

177voto

Travis Gockel Points 11043

Sur les systèmes d'exploitation de type UNIX, il existe sysconf .

#include <unistd.h>

unsigned long long getTotalSystemMemory()
{
    long pages = sysconf(_SC_PHYS_PAGES);
    long page_size = sysconf(_SC_PAGE_SIZE);
    return pages * page_size;
}

Sous Windows, il y a GlobalMemoryStatusEx :

#include <windows.h>

unsigned long long getTotalSystemMemory()
{
    MEMORYSTATUSEX status;
    status.dwLength = sizeof(status);
    GlobalMemoryStatusEx(&status);
    return status.ullTotalPhys;
}

Alors fais juste un peu de fantaisie #ifdef et vous serez prêt à partir.

0 votes

Je ne pense pas que tu seras rétrogradé pour ça, puisque c'est est réellement utile. Nous pouvons suggérer que c'est une mauvaise idée autant que nous le voulons, mais si quelqu'un veut vraiment faire quelque chose de stupide (bien que j'hésite à utiliser ce mot), qui sommes-nous pour lui refuser les outils ?

13 votes

Ce n'est pas que je veuille utiliser toute la mémoire, c'est que je ne veux pas charger trop de données que je ne peux pas traiter avec la mémoire disponible (je veux rester dans un espace inutilisé ou un espace qui ne sera probablement pas accédé par d'autres processus). Encore une fois, je ne veux pas être stupide et vouloir allouer toute la mémoire disponible, mais je veux décider quelle limite je dois mettre à l'application pour qu'elle n'absorbe pas toute la mémoire et ne se plante pas.

1 votes

Pour certains systèmes d'exploitation sysctl peut être une meilleure alternative à sysconf . Voir man 3 sysctl .

37voto

Paresh M Points 111

Il y a des raisons de vouloir faire cela dans le HPC pour les logiciels scientifiques. (Pas les logiciels de jeux, web, commerciaux ou embarqués). Les logiciels scientifiques utilisent régulièrement des téraoctets de données pour effectuer un calcul (ou une exécution) (et ce pendant des heures ou des semaines) - toutes ces données ne peuvent pas être stockées en mémoire (et si un jour vous me dites qu'un téraoctet est la norme pour tout PC, tablette ou téléphone, on s'attendra à ce que les logiciels scientifiques gèrent des pétaoctets ou plus). La quantité de mémoire peut également dicter le type de méthode/algorithme qui a du sens. L'utilisateur n'a pas toujours envie de décider de la mémoire et de la méthode - il a d'autres chats à fouetter. Le programmeur doit donc avoir une bonne idée de ce qui est disponible (4 Go, 8 Go, 64 Go ou plus de nos jours) pour décider si une méthode fonctionnera automatiquement ou si une méthode plus laborieuse doit être choisie. Le disque est utilisé mais la mémoire est préférable. Et les utilisateurs de ces logiciels ne sont pas encouragés à faire trop de choses sur leur ordinateur lorsqu'ils exécutent ces logiciels - en fait, ils utilisent souvent des machines/serveurs dédiés.

0 votes

Ce n'était pas exactement un logiciel scientifique, plus que la construction d'un cadre ETL, bien sûr, il était destiné à fonctionner sur des serveurs dédiés. Probablement, il avait besoin d'admettre une mémoire maximale autorisée, comme Java ou Maltab, comme paramètre de démarrage.

2 votes

Il y a des raisons de le faire, du moins avec les logiciels de rendu. Vous voulez utiliser autant de mémoire que vous en avez. Par exemple : la mémoire physique disponible (× avec 0.5<<0.8) sera la limite pour la taille de la carte de photons. + quelques min(physi, 2GiB) pour éviter que les machines avec 256GB de RAM prennent une éternité pour construire la photonmap. mais quand même. Vous pouvez aussi imaginer l'itinérance dans les jeux, j'ai vu des moteurs faire entrer et sortir des actifs pour maintenir un objectif de mémoire. plus vous avez de mémoire, plus vous pouvez voir loin.

16voto

mikelong Points 2034

Il n'y a pas de moyen indépendant de la plate-forme pour faire cela, les différents systèmes d'exploitation utilisent différentes stratégies de gestion de la mémoire.

Ces autres questions de stack overflow vous aideront :

Vous devez cependant faire attention : il est notoirement difficile d'obtenir une valeur "réelle" pour la mémoire disponible dans linux. Ce que le système d'exploitation affiche comme étant utilisé par un processus n'est pas une garantie de ce qui est réellement alloué pour le processus.

Il s'agit d'un problème courant lors du développement de systèmes linux embarqués tels que les routeurs, où vous voulez mettre en mémoire tampon autant que le matériel le permet. Voici un lien vers un exemple montrant comment obtenir cette information dans un linux (en C) :

0 votes

Linux utilise l'allocation paresseuse, vous pouvez garantir que la mémoire est allouée en y écrivant.

9voto

Paul R Points 104036

Exemple de Mac OS X utilisant sysctl ( man 3 sysctl ) :

#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/sysctl.h>

int main(void)
{
    int mib[2] = { CTL_HW, HW_MEMSIZE };
    u_int namelen = sizeof(mib) / sizeof(mib[0]);
    uint64_t size;
    size_t len = sizeof(size);

    if (sysctl(mib, namelen, &size, &len, NULL, 0) < 0)
    {
        perror("sysctl");
    }
    else
    {
        printf("HW.HW_MEMSIZE = %llu bytes\n", size);
    }
    return 0;
}

(peut aussi fonctionner sur d'autres systèmes d'exploitation de type BSD ?)

6 votes

Cela renvoie la mémoire physique totale du système, et non la mémoire disponible (libre).

3voto

MSalters Points 74024

La fonction "officielle" de cette est était std::get_temporary_buffer() . Cependant, vous pourriez vouloir tester si votre plateforme a une implémentation décente. Je comprends que toutes les plateformes ne se comportent pas comme souhaité.

4 votes

Cette fonction est dépréciée en C++17 et a été éliminée en C++20.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X