Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++ > Langage
Langage Langage C++, Programmation Orientée Objet, Templates, etc. Avant de poster : FAQ C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 21/02/2013, 19h32   #1
Kaluza
Membre du Club
 
Homme
Doctorant en Astrophysique
Inscription : mars 2009
Messages : 283
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Doctorant en Astrophysique
Secteur : Enseignement

Informations forums :
Inscription : mars 2009
Messages : 283
Points : 67
Points : 67
Par défaut Tester la mémoire disponible pour l'exécution du programme a son démarrage en C++11 standard ?

Bonjour.

Je souhaiterais que mon code teste la mémoire disponible pour son exécution a son démarrage, et cela en C++11 standard (pas de call system). J'ai besoin d'un chiffre approximatif (à 100Mo près environ), pas de la valeur exacte. Que pensez vous du code suivant : (on ajoute des éléments d'1Mo à une liste jusqu'à saturation, et l'on fait une deuxième passe avec une autre liste au cas où la limitation soit liée à l'implémentation de la liste)

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <array>
#include <list>
#include <initializer_list>
#include <stdexcept>
 
int main(int argc, char* argv[])
{
    static const long long int megabyte = 1024*1024;
    std::array<char, megabyte> content({{'a'}});
    std::list<decltype(content)> list1;
    std::list<decltype(content)> list2;
    const long long int n1 = list1.max_size();
    const long long int n2 = list2.max_size();
    long long int i1 = 0;
    long long int i2 = 0;
    long long int result = 0;
    for (i1 = 0; i1 < n1; ++i1) {
        try {
            list1.push_back(content);
        }
        catch (const std::exception&) {
            break;
        }
    }
    for (i2 = 0; i2 < n2; ++i2) {
        try {
            list2.push_back(content);
        }
        catch (const std::exception&) {
            break;
        }
    }
    list1.clear();
    list2.clear();
    result = (i1+i2)*sizeof(content);
    std::cout<<"Memory available for program execution = "<<result/megabyte<<" MB"<<std::endl;
    return 0;
}
Est-ce dangereux ou est-ce parfaitement ok de faire cette opération au lancement du programme ? (si vous avez une solution plus élégante, je suis preneur).

Merci beaucoup.
Kaluza est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2013, 21h12   #2
koala01
Modérateur
 
Avatar de koala01
 
Philippe Dunski
Inscription : octobre 2004
Messages : 8 612
Détails du profil
Informations personnelles :
Nom : Philippe Dunski
Âge : 41

Informations forums :
Inscription : octobre 2004
Messages : 8 612
Points : 13 282
Points : 13 282
Envoyer un message via MSN à koala01 Envoyer un message via Skype™ à koala01
Salut,

Je crains hélas que ce ne soit dangereux, du moins, sous windows et en 32 bits.

Il y a eu assez récemment une discussion dans laquelle le PO s'étonnait de l'impossibilité d'allouer de la mémoire après avoir atteint un point de saturation et supprimé pas mal d'éléments, mais je ne retombe décidément plus dessus

Pour ce que j'ai retenu de la discussion en question, il y a un problème "architectural" au niveau de la gestion de mémoire sur windows, avec un comportement différent en fonction de la quantité de mémoire allouée à la fois (un comportement différent entre la libération d'un block de plus de 5 Mb et celle d'un block de moins de 5Mb, si mes souvenirs sont bons).

Enfin, le problème est qu'une partie seulement de la mémoire est correctement libérée (et dans le cas du PO, il s'agissait de la plus petite partie qui était libérée), l'autre ne l'étant pas

Tu cours donc le risque qu'une partie seulement de la mémoire ne soit libérée après ce test, ce qui reviendrait à n'avoir que... ce peu de mémoire disponible.

Et comme je présume que ton but est quand meme de continuer à travailler après avoir évalué la quantité de mémoire disponible, je présume aussi qu'il est pour toi hors de question de mettre fin à l'application afin de récupérer la mémoire perdue

EDIT: ben voilà, j'ai retrouvé la discussion en question... Intéresse toi surtout à l'intervention #14 de Arzar
__________________
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
je ne répondrai à aucune question technique par E-mail, message visiteur ou message privé
Vous avez obtenu votre réponse pensez au bouton en bas de page
koala01 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/02/2013, 13h57   #3
leternel
Membre Expert
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 182
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : juin 2007
Messages : 1 182
Points : 2 496
Points : 2 496
Bonjour,
Je pense que le problème, c'est de vouloir connaitre une caractéristique du système (la mémoire disponible), en se limitant aux seuls possibilitées d'un langage conçu "hors système".
C'est improbable de pouvoir y parvenir en toute situation.

Il faut passer par les API systèmes.
Mais rare sont les cas où tu dois t'adapter à 75 API différentes.
__________________
Mes principes de bases du codeur qui veut pouvoir dormir:
  • Une variable de moins est une source d'erreur en moins.
  • Un pointeur de moins est une montagne d'erreurs en moins.
  • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
  • La plus sotte des questions est celle qu'on ne pose pas.
leternel est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/02/2013, 15h00   #4
Emmanuel Deloget
Expert Confirmé Sénior
 
Homme Emmanuel Deloget
Développeur informatique
Inscription : septembre 2007
Messages : 1 826
Détails du profil
Informations personnelles :
Nom : Homme Emmanuel Deloget
Âge : 37
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : septembre 2007
Messages : 1 826
Points : 4 381
Points : 4 381
Citation:
Envoyé par Kaluza Voir le message
Bonjour.

Je souhaiterais que mon code teste la mémoire disponible pour son exécution a son démarrage, et cela en C++11 standard (pas de call system). J'ai besoin d'un chiffre approximatif (à 100Mo près environ), pas de la valeur exacte. Que pensez vous du code suivant : (on ajoute des éléments d'1Mo à une liste jusqu'à saturation, et l'on fait une deuxième passe avec une autre liste au cas où la limitation soit liée à l'implémentation de la liste)

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <array>
#include <list>
#include <initializer_list>
#include <stdexcept>
 
int main(int argc, char* argv[])
{
    static const long long int megabyte = 1024*1024;
    std::array<char, megabyte> content({{'a'}});
    std::list<decltype(content)> list1;
    std::list<decltype(content)> list2;
    const long long int n1 = list1.max_size();
    const long long int n2 = list2.max_size();
    long long int i1 = 0;
    long long int i2 = 0;
    long long int result = 0;
    for (i1 = 0; i1 < n1; ++i1) {
        try {
            list1.push_back(content);
        }
        catch (const std::exception&) {
            break;
        }
    }
    for (i2 = 0; i2 < n2; ++i2) {
        try {
            list2.push_back(content);
        }
        catch (const std::exception&) {
            break;
        }
    }
    list1.clear();
    list2.clear();
    result = (i1+i2)*sizeof(content);
    std::cout<<"Memory available for program execution = "<<result/megabyte<<" MB"<<std::endl;
    return 0;
}
Est-ce dangereux ou est-ce parfaitement ok de faire cette opération au lancement du programme ? (si vous avez une solution plus élégante, je suis preneur).

Merci beaucoup.
Le code est d'une part dangereux, et d'autre part il ne marche pas - parce qu'il va réserver de la mémoire sans nécessairement commiter les pages (c'est à dire qu'il va augmenter la mémoire virtuelle réservée pour le processus, mais ne liera pas nécessairement les pages de mémoire physiques à cette mémoire virtuelle). Résultat, tu va avoir l'illusion d'avoir toute la mémoire pour toi - mais ce n'est que de la mémoire virtuelle, qui n'a pas d'existence réelle. Lorsque tu tenteras d'accéder en écriture à une partie de cette mémoire, l'OS n'arrivera pas à lier la mémoire virtuelle utilisée à de la mémoire physique, et va te sortir une erreur "page fault" (et ton programme va planter).

De plus, ce type de code à un autre problème : si tu arrives à réserver toute la mémoire physique, tu va rendre ton système instable - il suffit qu'un autre processus important ait besoin de mémoire et bam, c'est ton OS qui doit redémarrer.

C++ ne permet pas d'obtenir ce genre d'informations, pour une très simple raison : C++ n'a pas vocation à dire aux OS quels services ils doivent offrir. C'est pour ça que ce sont des fonctions dépendantes de OS qui fournissent ce genre de renseignements.
__________________
[FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.
Emmanuel Deloget est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 13h17.


 
 
 
 
Partenaires

Hébergement Web