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

Java Discussion :

Question de sémantique et de mémoire autour de Java


Sujet :

Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2007
    Messages : 103
    Points : 66
    Points
    66
    Par défaut Question de sémantique et de mémoire autour de Java
    Bonjour,

    Un débat est né autour des fuites mémoires et des programmes Java dans notre bureau

    Certains soutiennent qu'une fuite mémoire est un problème système dû notamment à des programmes zombies ou processus, objet non (ou plus) référencé dans la JVM mais existant encore. Hors un processus référencé dans la JVM peut produire un out.of.memory (soit la taille de la heap est mal dimensionnée soit le processus a une mauvaise gestion de la mémoire par exemple en gardant une référence sur les objet qu'il crée et le GC ne peut pas les supprimer).


    Question:

    Peut on dire qu'un processus Java qui a "une mauvaise gestion de la mémoire" provoque une fuite mémoire ou est ce qu'il existe (ou pas) un autre nom pour ce type d'erreur (erreur de conception en générale)? Quel définition donnée vous à fuite mémoire?


    Autre question:

    Une consommation en dent de scie de la mémoire de la JVM peut-elle provenir d'une "fuite mémoire" (si on peut le nommer ainsi). En clair nous avons un processus Java qui fait passer la mémoire de la JVM de 20% à 80% en quelques secondes (<10 secondes). Le GC passe et la mémoire redescend à 20%. Ce cycle est sans fin.

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par LeCogiteur Voir le message
    Peut on dire qu'un processus Java qui a "une mauvaise gestion de la mémoire" provoque une fuite mémoire ou est ce qu'il existe (ou pas) un autre nom pour ce type d'erreur (erreur de conception en générale)? Quel définition donnée vous à fuite mémoire?
    On pourrait parler de "fuite mémoire", puisqu'il s'agit d'une consommation abusive de la mémoire à cause de références que l'on conserve inutilement...


    Citation Envoyé par LeCogiteur Voir le message
    Une consommation en dent de scie de la mémoire de la JVM peut-elle provenir d'une "fuite mémoire" (si on peut le nommer ainsi). En clair nous avons un processus Java qui fait passer la mémoire de la JVM de 20% à 80% en quelques secondes (<10 secondes). Le GC passe et la mémoire redescend à 20%. Ce cycle est sans fin.
    Non. S'il y a fuite mémoire la consommation ne ferait qu'augmenter (puisque les objets ne sont pas libérés).
    Une courbe en dent de scie signifie bien que la mémoire est libérée.


    Cela peut être lié à une utilisation abusive temporaire (des objets qu'on stocke inutilement en static ou variable d'instance alors que ce sont des variables locales) ou tout simplement à l'utilisation d'un grand nombre d'objet...

    Le GC fait son travail normalement. Ton appli crées beaucoup d'objet qui augmente l'occupation mémoire, puis le GC nettoie tout cela.
    Selon la JVM le GC peut avoir tendance à privilégier l'allocation à la libération de la mémoire (c'est à dire qu'il ne cherchera pas à libérer la mémoire à tout prix tant qu'elle n'a pas atteint un certain stade).

    Du coup si ton appli consomme beaucoup de mémoire cela peut aboutir à ce genre de courbe.


    a++

  3. #3
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Citation Envoyé par LeCogiteur Voir le message
    Peut on dire qu'un processus Java qui a "une mauvaise gestion de la mémoire" provoque une fuite mémoire ou est ce qu'il existe (ou pas) un autre nom pour ce type d'erreur (erreur de conception en générale)? Quel définition donnée vous à fuite mémoire?
    En général, on parle de fuite mémoire en C/C++ quand on perd la valeur d'un pointeur ou de la mémoire a été allouée; Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char* p;
    p = new char[10];
    p = new char[20];
    A la 2e allocation, on perd la valeur du pointeur et du coup, on ne peut plus la liberer.

    En java, ce cas n'est pas possible puisqu'une fois que la variable est ré-affectée, le GC le libérera automatiquement. Ceci dit, il est fréquent de garder des référence non voulues dans une arraylist, par exemple, et ca peut finir en out of memory.

    Citation Envoyé par LeCogiteur Voir le message
    Une consommation en dent de scie de la mémoire de la JVM peut-elle provenir d'une "fuite mémoire" (si on peut le nommer ainsi). En clair nous avons un processus Java qui fait passer la mémoire de la JVM de 20% à 80% en quelques secondes (<10 secondes). Le GC passe et la mémoire redescend à 20%. Ce cycle est sans fin.
    Comme l'a dit adiGuba, par définition, si la consommation mémoire redescend, c'est qu'elle a été libérée. Donc ce n'est pas une fuite mémoire. En pratique, le GC ne cherche pas à avoir la consommation mémoire minimum et ne libère pas forcément la mémoire dès que possible. Si la mémoire vient à manquer, avant le out of memory, le GC va essayer de libérer tout ce qu'il peut. Ca peut meme causer des ralentissements dans l'appli.

    Si tu trouves la consommation mémoire excessive, il existe des parametres pour la JVM pour la gestion de la mémoire :
    - Xmx : mémoire maximale que peut utiliser la JVM
    - Xms : mémoire initiale de la JVM

    Exemple : javaw -Xms64m -Xmx128m -jar MonJar.jar

  4. #4
    Membre expérimenté Avatar de nchal
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 512
    Points : 1 656
    Points
    1 656
    Par défaut
    Je me demande si on forçant l'exécution du GC, on peut éviter l'utilisation en dent de scie de la mémoire (vue qu’apparemment c'est un problème pour toi).
    Je ne connais pas le fonctionnement du GC mais on va dire qu'il s'exécute après que certains senseurs l'informe qu'il faut faire qqchose (plus de mémoire, déréférencement d'un objet, timer, ...)
    Donc si tu force l'exécution du GC, tu passes outre ses "senseurs" mais tu évites les dents de scie.
    Si la réponse vous convient, un petit ça encourage.
    Avant tout nouveau post, pensez à : la FAQ, Google et la fonction Recherche
    Si vous devez poster, pensez à: Ecrire en français, la balise [CODE] (#) et surtout

  5. #5
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par nchal Voir le message
    Je me demande si on forçant l'exécution du GC, on peut éviter l'utilisation en dent de scie de la mémoire (vue qu’apparemment c'est un problème pour toi).
    Je ne connais pas le fonctionnement du GC mais on va dire qu'il s'exécute après que certains senseurs l'informe qu'il faut faire qqchose (plus de mémoire, déréférencement d'un objet, timer, ...)
    Donc si tu force l'exécution du GC, tu passes outre ses "senseurs" mais tu évites les dents de scie.
    Mauvaise idée, ça risque de provoquer des lenteurs et de surcharger l'activité du garbage collector.

    http://blog.aliecom.com/pourquoi-il-...ser-system-gc/

  6. #6
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    @nchal : c'est une très mauvaise idée ! Tu risques juste de faire travailler le GC plus souvent et pour rien, et cela ne résoudra en aucun cas le "problème".
    L'appel explicite du GC n'aboutit à rien si ce n'est de plomber les performances globales...


    Si ton application utilise beaucoup de mémoire, il faut d'abord l'analyser pour savoir si c'est normal ou pas (genre des objets créés inutilement dans de grosse boucle, créés dans des scopes trop large, etc.).

    Ensuite si le travail du GC ne convient pas, on peut le tuner via les options de la JVM :
    http://www.oracle.com/technetwork/ja...-6-140523.html
    http://www.oracle.com/technetwork/ja...sp-140102.html


    Mais surtout ne jamais appeler forcer le GC dans le code !!!


    a++

  7. #7
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    @LeCogiteur : "Certains soutiennent qu'une fuite mémoire est un problème système dû notamment à des programmes zombies ou processus"
    A part le processus que tu crées en lançant le main(), il n'y a pas d'autres "processus"*, juste des "processus léger" ou "thread".
    * : Il peut y avoir création de processus si tu lances un programme dans ton programme.

    Je pense qu'on peut créer des fuites de mémoire si on ferme mal les flux, mais je ne crois pas que le GC peut tous les détecter.

    @nchal : Il est possible de forcer l'exécution du GC avec l'instruction "System.gc();" mais généralement c'est à bannir
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  8. #8
    Membre expérimenté Avatar de nchal
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 512
    Points : 1 656
    Points
    1 656
    Par défaut
    C'est pourquoi je demandais si c'était une bonne idée. Apparemment, j'ai une réponse : NON !!
    Si la réponse vous convient, un petit ça encourage.
    Avant tout nouveau post, pensez à : la FAQ, Google et la fonction Recherche
    Si vous devez poster, pensez à: Ecrire en français, la balise [CODE] (#) et surtout

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2007
    Messages : 103
    Points : 66
    Points
    66
    Par défaut
    Merci pour toutes ces réponses . Je vois que ça fait débat aussi.

    J'ai bien noté qu'une utilisation de la mémoire en dent de scie n'a rien avoir avec une fuite mémoire. D'un point de vue personnelle, je trouvais que le passage du gc plusieurs fois par minute anormale. En vous avez raison puisqu'à première vue il semblerait que se soit un problème extérieur. Le disque dur semble défectueux (c'est un serveur Windows). Pour info, cette appli Java travaille sur de nombreux fichiers et les I/O semblent longs, les traitements sont ralentis.

    Concernant la définition de fuite mémoire: si je résume ,

    Citation Envoyé par Gugelhupf Voir le message
    @LeCogiteur : "Certains soutiennent qu'une fuite mémoire est un problème système dû notamment à des programmes zombies ou processus"
    A part le processus que tu crées en lançant le main(), il n'y a pas d'autres "processus"*, juste des "processus léger" ou "thread".
    * : Il peut y avoir création de processus si tu lances un programme dans ton programme.

    Je pense qu'on peut créer des fuites de mémoire si on ferme mal les flux, mais je ne crois pas que le GC peut tous les détecter.
    Citation Envoyé par hwoarang Voir le message
    En java, ce cas n'est pas possible puisqu'une fois que la variable est ré-affectée, le GC le libérera automatiquement. Ceci dit, il est fréquent de garder des référence non voulues dans une arraylist, par exemple, et ca peut finir en out of memory.
    Citation Envoyé par adiGuba Voir le message
    Salut,


    On pourrait parler de "fuite mémoire", puisqu'il s'agit d'une consommation abusive de la mémoire à cause de références que l'on conserve inutilement...



    Non. S'il y a fuite mémoire la consommation ne ferait qu'augmenter (puisque les objets ne sont pas libérés).
    Une courbe en dent de scie signifie bien que la mémoire est libérée.
    Si je vous comprend bien il n'y a pas en Java de fuite mémoire possible sauf si cas exceptionnel lors d'une mauvaise gestion des flux (comme par exemple oublier de fermer les connexions BDD, peut être). Par abus de langage, on pourrait (pour reprendre @adiGuba) dire q'une utilisation abusive de la mémoire conduisant à un outOfMemory est une fuite mémoire (alors que techniquement elle n'a pas eu lieu mais maîtrisé par la JVM via une exception et l'arrêt du programme)? ou alors le fait que l'on garde une référence sur les objets fait que c'est définitivement pas une fuite mémoire. Peut-être que l'outOfMemory est déclenché par la JVM afin de prévenir (et empêcher) un buffer overflow.
    dans la documentation d'Oracle http://docs.oracle.com/javase/7/docs.../memleaks.html:
    One common indication of a memory leak is the java.lang.OutOfMemoryError error.
    Fuite de mémoire (memory leak) est peut être abusivement utilisée pour désigner un buffer overflow. Car la JVM contrôle normalement la mémoire qu'il lui est alloué (sauf erreur d'implémention de la JVM).
    Je crois que je me mélange les pinceaux. J'avoue avoir encore un peu de mal à comprendre désolé.


    Je sais je pinaille mais la sémantique est important pour certain

  10. #10
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeCogiteur Voir le message
    J'ai bien noté qu'une utilisation de la mémoire en dent de scie n'a rien avoir avec une fuite mémoire. D'un point de vue personnelle, je trouvais que le passage du gc plusieurs fois par minute anormale.
    C'est peut-être anormale ou pas... Mais ca dépend surtout de ton code, de ce qu'il est censé faire et de ce qu'il fait.
    Impossible de te répondre sans en savoir plus sur ton code...


    Citation Envoyé par LeCogiteur Voir le message
    En vous avez raison puisqu'à première vue il semblerait que se soit un problème extérieur. Le disque dur semble défectueux (c'est un serveur Windows). Pour info, cette appli Java travaille sur de nombreux fichiers et les I/O semblent longs, les traitements sont ralentis.
    Le disque dur ou les lenteurs d'I/O n'ont rien à voir avec une forte consommation de mémoire...
    Des traitements "ralentis" peuvent aussi être lié à un code inefficace qui créerait trop d'objets temporaires inutilement (en plus ca collerait au fait que l'application consomme trop de mémoire).

    Mais il faut profiler l'application pour déterminer l'origine du problème...


    Citation Envoyé par LeCogiteur Voir le message
    Si je vous comprend bien il n'y a pas en Java de fuite mémoire possible sauf si cas exceptionnel lors d'une mauvaise gestion des flux (comme par exemple oublier de fermer les connexions BDD, peut être). Par abus de langage, on pourrait (pour reprendre @adiGuba) dire q'une utilisation abusive de la mémoire conduisant à un outOfMemory est une fuite mémoire (alors que techniquement elle n'a pas eu lieu mais maîtrisé par la JVM via une exception et l'arrêt du programme)? ou alors le fait que l'on garde une référence sur les objets fait que c'est définitivement pas une fuite mémoire. Peut-être que l'outOfMemory est déclenché par la JVM afin de prévenir (et empêcher) un buffer overflow.
    dans la documentation d'Oracle http://docs.oracle.com/javase/7/docs.../memleaks.html:
    La doc d'Oracle parle bien de fuite de mémoire.

    C'est vrai qu'en Java on ne peut pas "perdre" un pointeur et ne plus pouvoir le libérer comme dans certains langage, car le GC gère tout cela à notre place.
    Mais au final cela revient un peu à la même chose que la mémoire ne soit pas libérée parce qu'on a perdu un pointeur, ou parce qu'on garde une référence inutilement.
    Le résultat est le même : une occupation mémoire dont on ne se sert plus, mais qui reste inutilisable pour autre chose...

    Citation Envoyé par LeCogiteur Voir le message
    Fuite de mémoire (memory leak) est peut être abusivement utilisée pour désigner un buffer overflow.
    Non le buffer overflow n'a rien à voir. Tu peux avoir un buffer overflow sans avoir de fuite mémoire, et inversement.


    a++

  11. #11
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    le Glaneur de mémoire n'est pas obligé de répondre aux demandes explicites qui lui sont faites par gc().
    il me semble que tu es en face d'un problème de syntonisation ("tuning") : c'est un vrai métier qui consiste à bien connaître le comportement de l'application, la qualité de service que l'on veut obtenir et après faire joujou avec le choix du GC et les tailles des zones du tas comme l'Eden.
    on peut par exemple abaisser volontairement les performances globales pour améliorer les performances instantanées (baisse des performances de service à l'instant T, baisses dues au passage du GC): parallel GC + Eden plus petit -> le GC tourne comme un fou mais ça limite les "dents de scie"
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

  12. #12
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Citation Envoyé par LeCogiteur Voir le message
    Fuite de mémoire (memory leak) est peut être abusivement utilisée pour désigner un buffer overflow.
    Fuite de mémoire: une zone de mémoire est allouée mais non libérée, et inutilisable.
    Pour moi, à partir du moment où l'on ne peut plus utiliser cette zone, que l'on ait une référence/pointeur sur cette zone ou pas, c'est une fuite de mémoire.

    Buffer overflow: une zone de mémoire est allouée, mais une écriture s'est faite en dehors de cette zone.

    Out.of.memory: la zone de mémoire ne peut pas être allouée.

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/10/2010, 10h21
  2. Question sur la libération de mémoire
    Par adaneels dans le forum C#
    Réponses: 16
    Dernier message: 17/06/2009, 18h47
  3. [W3C] Questions sur Sémantique
    Par Furiuos dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 17/12/2007, 14h08
  4. Question existentielle sur allocation de mémoire
    Par keepmeahug dans le forum C++
    Réponses: 6
    Dernier message: 03/05/2007, 12h08
  5. Question sur l'allocation de mémoire
    Par Fonzy007 dans le forum Linux
    Réponses: 8
    Dernier message: 26/12/2006, 09h29

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