1. NOM

madvise - Configurer l'utilisation de la mémoire

2. SYNOPSIS

#include <sys/mman.h>

int madvise(void *addr, size_t length, int advice);

Exigences de macros de test de fonctionnalités pour la glibc (consultez feature_test_macros(7)) :

madvise() : _BSD_SOURCE

3. DESCRIPTION

L'appel système madvise() conseille le noyau sur la façon de gérer la pagination sur l'intervalle d'adresses débutant à l'adresse addr et de taille length (en octets). Il permet à une application d'indiquer au noyau l'utilisation qu'elle compte faire de certaines zones de mémoire partagée ou projetée de façon à ce que le noyau puisse choisir les techniques de lecture anticipée et de mise en cache appropriées. Cet appel ne modifie pas la sémantique de l'application (sauf dans le cas de MADV_DONTNEED), mais peut avoir un impact sur ses performances. Le noyau est libre d'ignorer le conseil.

Le conseil est spécifié par le paramètre advice qui peut prendre les valeurs

  • MADV_NORMAL
        Pas de traitement particulier. Il s'agit du comportement par défaut.
  • MADV_RANDOM
        Prévoit des accès aux pages dans un ordre aléatoire. (Ainsi, la lecture anticipée sera moins utile qu'elle ne l'est en général.)
  • MADV_SEQUENTIAL
        prévoit des accès aux pages dans un ordre séquentiel. (Aussi, les pages d'un intervalle donné peuvent être systématiquement lues par anticipation, et peuvent être libérées rapidement après avoir été accédées.)
  • MADV_WILLNEED
        Prévoit un accès dans un futur proche. (Ainsi, lire quelques pages de façon anticipée peut être une bonne idée.)
  • MADV_DONTNEED
        Ne prévoit pas d'accès dans un futur proche. (Pour l'instant, l'application en a fini avec l'intervalle considéré, ainsi le noyau peut(hyil libérer les ressources associées à ce dernier.) Les accès ultérieurs aux pages de l'intervalle réussiront, mais résulteront soit en un rechargement du fichier projeté sous(hyjacent (consultez mmap(2)), soit en un remplissage avec des zéros pour les pages sans fichier.
  • MADV_REMOVE (depuis Linux 2.6.16) Libérer un ensemble contigu de pages et les ressources correspondantes. Actuellement, ceci n'est possible que sur shmfs/tmpfs ; les autres systèmes de fichiers renvoient l'erreur ENOSYS.
  • MADV_DONTFORK (depuis Linux 2.6.16) Ne pas rendre les pages de cet intervalle disponibles au fils après un fork(2). Ceci est utile pour empêcher la sémantique de copie à l'écriture de changer l'emplacement physique d'une page si le père y écrit après un fork(2). (De tels déplacements posent des problèmes si le matériel accède directement à la page (DMA)).
  • MADV_DOFORK (depuis Linux 2.6.16)
        Annuler l'effet de MADV_DONTFORK et restaurer le comportement par défaut, où une projection en mémoire est héritée après un fork(2).
  • MADV_HWPOISON (depuis Linux 2.6.32)
        Empoisonne une page et la traite comme une corruption de la mémoire matérielle. Cette opération n'est disponible que pour les processus privilégiés (CAP_SYS_ADMIN). À la suite de cette opération, le processus appelant peut recevoir un SIGBUS et la page devenir non affectée. Cette fonctionnalité est prévue pour tester le code de gestion des erreurs de la mémoire ; elle n'est disponible que si le noyau a été configuré avec CONFIG_MEMORY_FAILURE.
  • MADV_SOFT_OFFLINE (depuis Linux 2.6.33)
        Déconnecte les pages dans l'intervalle spécifié par addr et length. La mémoire de chaque page dans l'intervalle spécifié est préservée (lors du prochain accès, le même contenu sera visible, mais dans une nouvelle page physique), et la page originale est déconnectée (ce qui signifie qu'elle n'est plus utilisée, et plus prise en compte par les mécanismes habituels de gestion de la mémoire). L'effet de l'opération MADV_SOFT_OFFLINE est invisible au processus appelant (c'est-à-dire qu'elle n'en change pas la sémantique). Cette fonctionnalité est prévue pour tester le code de gestion des erreurs de la mémoire ; elle n'est disponible que si le noyau a été configuré avec CONFIG_MEMORY_FAILURE.
  • MADV_MERGEABLE (depuis Linux 2.6.32)
        Active la fusion des pages identiques par le noyau (Kernel Samepage Merging, ou KSM) pour les pages dans l'intervalle spécifié par addr et length. Le noyau analyse régulièrement les régions de la mémoire utilisateur qui ont été marquées comme pouvant être fusionnées, à la recherche de pages avec un contenu identique. Elles sont remplacées par une page unique protégée en écriture (qui sera automatiquement recopiée si un processus veut plus tard modifier le contenu de la page). KSM ne fusionne que les pages anonymes privées (consultez mmap(2)). La fonctionnalité KSM est prévue pour des applications qui génèrent beaucoup d'instances des mêmes données (par exemple des systèmes de virtualisation tels que KVM). Elle peut nécessiter beaucoup de ressources de traitement ; à utiliser avec précaution. Consultez le fichier Documentation/vm/ksm.txt dans les sources du noyau Linux pour plus de détails. Les opérations MADV_MERGEABLE et MADV_UNMERGEABLE ne sont disponibles que si le noyau a été configuré avec CONFIG_KSM.
  • MADV_UNMERGEABLE (depuis Linux 2.6.32)
        Annuler l'effet d'une opération MADV_MERGEABLE précédente sur l'intervalle d'adresse spécifié ; KSM annule la fusion sur les pages qui avaient été fusionnées dans l'intervalle spécifié par addr et length.
  • MADV_HUGEPAGE (depuis Linux 2.6.38) Active la gestion transparente des pages immenses (Transparent Huge Pages, ou THP) pour les pages dans l'intervalle spécifié par addr et length. Actuellement, THP ne fonctionne qu'avec les pages anonymes privées (consultez mmap(2)). Le noyau analysera régulièrement les régions qui ont été marquées comme candidates aux pages immenses pour les remplacer par des pages immenses. Le noyau allouera aussi des pages immenses directement quand la région est naturellement alignée sur la taille de page immense (consultez posix_memalign(2)). Cette fonctionnalité est initialement prévue pour des applications qui utilisent de grosses projections de données et accèdent à de grosses zones de cette mémoire en même temps (par exemple les systèmes de virtualisation comme QEMU). Il peut très facilement gaspiller beaucoup de mémoire (par exemple une projection de 2 Mo qui n'accède qu'à un seul octet a pour conséquence 2 Mo de mémoire connectée au lieu d'une page de 4 ko). Consultez le fichier Documentation/vm/ktranshuge.txt dans les sources du noyau Linux pour plus de détails. Les opérations MADV_HUGEPAGE et MADV_NOHUGEPAGE ne sont disponibles que si le noyau a été configuré avec CONFIG_TRANSPARENT_HUGEPAGE.
  • MADV_NOHUGEPAGE (depuis Linux 2.6.38)
        S'assure que la mémoire dans l'intervalle spécifié par addr et length ne sera pas perdue dans des pages immenses.
  • MADV_DONTDUMP (depuis Linux 3.4)
        Exclue de l'image mémoire (« core dump ») les pages dans l'intervalle indiqué par addr et length. C'est utile pour les applications dont de larges zones de mémoire sont notoirement inutiles dans une image mémoire. L'effet de MADV_DONTDUMP est prioritaire sur le masque de bits configuré via /proc/PID/coredump_filter, consultez core(5).
  • MADV_DODUMP (depuis Linux 3.4)
        Annuler l'effet de MADV_DONTDUMP.

4. VALEUR RENVOYÉE

En cas de succès madvise() renvoie zéro. En cas d'erreur, il renvoie -1 et errno est positionné de façon adéquate.

5. ERREURS

  • EAGAIN
        Une ressource du noyau est temporairement indisponible.
  • EBADF
        La projection existe, mais la zone n'est pas associée à un fichier.
  • EINVAL
        Cette erreur peut survenir pour les raisons suivantes :

* 3 La valeur len est négative.

* addr n'est pas aligné sur une page.

* advice n'a pas une valeur valide.

* L'application tente de libérer des pages verrouillées ou partagées (avec MADV_DONTNEED).

* MADV_MERGEABLE ou MADV_UNMERGEABLE a été indiqué dans advice, mais le noyau n'a pas été configuré avec l'option CONFIG_KSM.

  • EIO
        (pour MADV_WILLNEED) Suivre la consigne de pagination sur cette zone dépasserait la limite maximale de mémoire physique utilisable par le processus.
  • ENOMEM
        (pour MADV_WILLNEED) Mémoire insuffisante ; échec de pagination.
  • ENOMEM
        Les adresses de l'intervalle spécifié ne sont pas projetées actuellement, ou n'appartiennent pas à l'espace d'adressage du processus.

6. CONFORMITÉ

POSIX.1b. POSIX.1-2001 spécifie l'appel posix_madvise(3) avec des constantes POSIX_MADV_NORMAL, etc. et un comportement proche de celui décrit ici. Il existe un appel similaire posix_fadvise(2) pour les accès aux fichiers. MADV_REMOVE, MADV_DONTFORK, MADV_DOFORK, MADV_HWPOISON, MADV_MERGEABLE et MADV_UNMERGEABLE sont spécifiques à Linux.

7. NOTES

7.1. Notes sur Linux

L'implémentation Linux actuelle (2.4.0) perçoit davantage cet appel système comme une commande que comme un conseil et est ainsi susceptible de renvoyer une erreur quand elle ne parvient pas à réaliser ce qu'elle devrait accomplir en réponse à ce conseil. (Consultez la description des ERREURS ci(hydessus.) Il s'agit d'un comportement non standard.

L'implémentation Linux nécessite que l'adresse addr soit alignée sur une page, et permet que length vaille zéro. S'il y a des parties de l'intervalle d'adresses spécifié qui ne sont pas projetées, la version Linux de madvise() les ignore et applique l'appel au reste de l'intervalle (mais renvoie ENOMEM comme il se doit).

8. VOIR AUSSI

getrlimit(2), mincore(2), mmap(2), mprotect(2), msync(2), munmap(2), core(5)

9. COLOPHON

Cette page fait partie de la publication 3.52 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies peuvent être trouvées à l'adresse http://www.kernel.org/doc/man-pages/.

10. TRADUCTION

Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>.

Stéphan Rafin (2002), Alain Portal <http://manpagesfr.free.fr/> (2006). Julien Cristau et l'équipe francophone de traduction de Debian (2006-2009).

Veuillez signaler toute erreur de traduction en écrivant à <>.

Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « LC_ALL=C man <section> <page_de_man> ».