IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

comment malloc() peut renvoyer null alors que le noyau utilise de la mémoire virtuelle


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 274
    Par défaut comment malloc() peut renvoyer null alors que le noyau utilise de la mémoire virtuelle
    Bonjour à tous,

    voila, le noyau utilise un système de pagination ce qui donne l'illusion que note systeme à une mémoire illimitée, et c'est grace a ce procédé que l'on peut lancer des programmes qui ont une taille bien supérieur à la capacité de la RAM. Ce que je ne comprends pas, c'est pourquoi via le systeme de mémoire virtuelle malloc peut renvoyer null.

    Merci d'avance pour vos éclaircissements.

  2. #2
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 270
    Par défaut
    malloc peut renvoyer NULL si tu as fait une demande d'allocation de 0 octet, ou si il y a une erreur, voir alors ERRNO.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    C'est surtout parce malloc() est spécifiée pour n'importe quel système. C'est un fonctionnement général qui permet de porter la fonction malloc() quelque soit (on le souhaite en tout cas) la manière dont travaille d'allocateur du système.

    Ce que tu décris est le fonctionnement d'un système particulier (ça ressemble à Linux). Il s'arrange comme il veut pour faire une implémentation de malloc() conforme à la norme tout en répondant à sa manière de gérer la mémoire.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Citation Envoyé par cosmoff Voir le message
    voila, le noyau utilise un système de pagination ce qui donne l'illusion que note systeme à une mémoire illimitée
    Mais ça reste une illusion.

    La taille de la mémoire virtuelle n'est pas illimitée. Elle est limitée par deux facteurs:
    1. La taille du support de cette mémoire virtuelle. Sous Linux, c'est généralement la taille de ta partition de swap sur le disque dur; Sous Windows, c'est la taille combinée des fichiers de pagination sur les différentes partitions des différents disques durs installés.
      La taille recommandée (ou réglée en vrai) pour ces supports peut varier, mais généralement ça ne dépasse pas deux ou trois fois la taille de la RAM.
    2. La taille de l'espace adressable par un processus: Vu que les OS modernes donnent aux processus (par défaut) un espace mémoire "plat", tu as une limite "hard" à ce que le processus peut adresser (sans passer par des mécanismes comme Address Windowing Extensions, en plus ou à la place de malloc()).
      • Pour un processus 32 bits, cette limite "hard" est 4Go.
      • Sous Windows, il y a une limite "soft" encore plus basse, car l'espace adressable est partagée entre une zone accessible en "user-mode", et une zone accessible uniquement en "kernel-mode". Par défaut, c'est coupé à la moitié, laissant au code "user-mode" d'un processus 2Go d'espace d'adressage, et pas plus.

    Si tu tentes d'allouer au-delà d'une de ces deux limites, l'allocation échouera et malloc() retournera NULL.

    Sur les anciens systèmes, on tendait à rencontrer la première limite en premier. Sur les systèmes récents, un processus 32 bits rencontrera la seconde limite, un processus 64 bits se heurtera à la première.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    551
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 551
    Par défaut
    Bonjour,
    Citation Envoyé par cosmoff Voir le message
    voila, le noyau utilise un système de pagination ce qui donne l'illusion que note systeme à une mémoire illimitée, et c'est grace a ce procédé que l'on peut lancer des programmes qui ont une taille bien supérieur à la capacité de la RAM. Ce que je ne comprends pas, c'est pourquoi via le systeme de mémoire virtuelle malloc peut renvoyer null.
    Merci d'avance pour vos éclaircissements.
    En plus de la réponse de @chrtophe, il faut comprendre que l'on a réellement la mémoire allouée, uniquement quand vous allez écrire des data/octet dans cette mémoire pas avant ni même après avoir fait char * buffer = malloc( 10 * sizeof *buffer );. C’est quand vous allez faire quelque chose du genre (void)memset(buffer, 0x0, BUFSIZ); que le système d'exploitation va vous attribuer la mémoire souhaitée en RAM en levant une exception pas avant.

    à bientôt.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Mais la mémoire en question est allouée dans la mémoire virtuelle dès le retour de malloc(), même si elle n'est pas encore "en RAM": l'OS a réservé cet espace, et tu n'auras pas d'erreur "out of memory" au moment où tu tentes d'écrire dedans (mais tu peux avoir une page fault qui causera un swap de la page en question entre le disque et la RAM).

    Du moins, sous Windows. Il est possible que Linux ait choisi la vitesse au détriment de la stabilité, mais c'est exactement ce qu'ils accusent Windows de faire...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    551
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 551
    Par défaut
    Non il y a aucune allocation de mémoire faite dans la mémoire virtuelle.

    malloc renvoie une adresse de la mémoire virtuelle, mais il n’alloue pas de la mémoire virtuelle, il la sollicite à travers des sous-routines ou appels système comme sbrk voire mmap selon l’implémentation faite a malloc sur le système d’exploitation sur lequel il est utilisé.

    Bref, lorsque vous accéder a l’adresse virtuelle en question, le MMU déclenche une erreur/faute de page, qui signifie qu’il n’y a pas de mémoire physique pour cette page virtuelle et qu’à ce moment-là, le système d’exploitation va se charger d’allouer de la mémoire physique pour la page virtuelle/adresse virtuelle en question. C’est donc le MMU, qui effectue tout le boulot de transformation des adresses virtuelles en une adresse physique; et a ma connaissance aucun système d'exploitation sur PC n'échappe à cette règle, et encore une fois tout dépend de la quantité de mémoire sollicitée et de la stratégie d'allocation qu'utilise la fonction malloc pour pouvoir réserver de la mémoire souhaitée et en disposer. Tout comme, cela dépend également de l'implémentation de la fonction qui varie d'un système a un autre.

  8. #8
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 270
    Par défaut
    malloc pioche dans le tas. Si celui-ci est plein, il est automatiquement agrandi en ajoutant une page virtuelle à l’espace d’adressage au processus. Lors du premier accès à ce nouvel espace, une exception est levée et le gestionnaire effectue l'allocation de la RAM physique.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Sous Windows, malloc() est un wrapper de HeapAlloc() qui, lors qu'il faut agrandir le tas (et donc, allouer plus de mémoire au processus), appelle VirtualAlloc().
    VirtualAlloc() supporte deux opérations, Reserve et Commit, mais aucune des deux n'est à propos de la mémoire physique:
    • Reserve alloue de l'espace d'adressage depuis l'espace d'adressage encore non-alloué du processus appelant (ce qui est indépendant de la "consommation mémoire" du processus; même avec 16Go de RAM tu peux avoir mille processus et "chacun réserve 1Go de son espace").
    • Commit alloue de la mémoire virtuelle (dans la limite de sa taille totale) pour l'associer à de l'espace d'adressage réservé. Cette opération n'a rien à voir avec la mémoire physique, et ne déclenche pas un swap in de la mémoire en question: Elle ne sera swapped in que quand on tentera de l'utiliser, par le mécanisme décrit par sambia39: La MMU déclenchera une interruption et l'OS mettra cette page en mémoire physique.
    • L'usage le plus simple (et le plus "malloc-like") de la fonction est de demander Reserve et Commit en même temps, en indiquant juste la taille de la mémoire qu'on veut allouer.

    (Au passage, si on veut forcer qu'une page soit en mémoire physique et y reste, on utilise VirtualLock)

    L'avantage de ce système, c'est que si le fichier de pagination et la mémoire physique sont tous les deux pleins (donc, si la mémoire virtuelle est pleine), l'allocation retourne NULL immédiatement, et si la mémoire virtuelle n'est pas pleine, l'allocation réussit et le swap-in ne peut pas échouer.
    [Supposant que le processus est mono-thread] Il n'y a donc aucun risque de situation où "malloc() retourne un pointeur non-nul, mais la tentative d'écrire dans la zone allouée cause une violation".

    Citation Envoyé par chrtophe Voir le message
    malloc pioche dans le tas. Si celui-ci est plein, il est automatiquement agrandi en ajoutant une page virtuelle à l’espace d’adressage au processus. Lors du premier accès à ce nouvel espace, une exception est levée et le gestionnaire effectue l'allocation de la RAM physique.
    Et à ce moment-là, l'OS est supposé vérifier qu'il a de la place soit dans le swapfile, soit dans la RAM, et dire "non" si les deux sont pleins.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 4
    Dernier message: 09/06/2010, 11h24
  2. Réponses: 4
    Dernier message: 18/01/2010, 12h38
  3. [AC-2002] Me.OpenArgs Null alors que ce n'est pas vrai
    Par jaffael dans le forum VBA Access
    Réponses: 3
    Dernier message: 08/06/2009, 17h32
  4. Réponses: 4
    Dernier message: 20/09/2006, 16h58
  5. [VBA Access] Champ texte null alors que l'objet existe bien.
    Par Caroline1 dans le forum VBA Access
    Réponses: 9
    Dernier message: 28/03/2006, 17h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo