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 :

spécifier l'accès à plus de RAM


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3
    Par défaut spécifier l'accès à plus de RAM
    Bonsoir,

    Je dispose d'une RAM de 2 Go.

    Au début de son exécution, mon programme Java indique "total memory in the JVM 5 177 344 bytes". J'ai vérifié que le chargement d'un programme avec peu d'instructions fournit le même résultat (Runtime.getRuntime().totalMemory()).

    Runtime.getRuntime().maxMemory() fournit : 66 650 112 bytes.


    Au cours de l'exécution, je crée des objets Java jusqu'à ce que Runtime.getRuntime().freeMemory() indique 316 574 bytes disponibles.


    Comment faire utiliser plus de RAM à un programme Java ?

    Merci par avance de votre réponse.

    Cordialement

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    par défaut, la jvm est limitée à 64M. Pour utiliser plus, il faut passer le paramètre -Xmx à la jvm:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java -Xmx1024m -jar monappli.jar
    Utilisera maximum 1G

    Attention que, quand java prend de la mémoire système pour sa jvm (exemple il est à 32M il a besoin de passer à 40M), celle-ci ne sera pas rendue tant que la JVM ne quittera pas. Si ton programme doit tourner longtemps, il faut faire gaffe à ne pas donner à la JVM plus que nécessaire.

  3. #3
    Membre Expert
    Avatar de natha
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 346
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Attention que, quand java prend de la mémoire système pour sa jvm (exemple il est à 32M il a besoin de passer à 40M), celle-ci ne sera pas rendue tant que la JVM ne quittera pas. Si ton programme doit tourner longtemps, il faut faire gaffe à ne pas donner à la JVM plus que nécessaire.
    Ce n'est pas tout à fait exact.
    Par défaut java rend la mémoire sous un certain ratio de mémoire utilisée / mémoire allouée. Je crois que par défaut c'est 70%.

    Pour qu'il libère plus souvent (genre 25% + 2 ou 3 petites choses) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=25 -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled
    Sinon allouer 1Go directement c'est un peu barbare. Prévoir 128Mo déjà pour commencer serait pas mal. Il faut penser à trouver les mauvaises gestions de mémoire dans le programme.

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par natha Voir le message
    Ce n'est pas tout à fait exact.
    Par défaut java rend la mémoire sous un certain ratio de mémoire utilisée / mémoire allouée. Je crois que par défaut c'est 70%.

    Pour qu'il libère plus souvent (genre 25% + 2 ou 3 petites choses) :
    Faut pas confondre la gestion mémoire au niveau du système et la gestion de la mémoire au sein de la jvm. Les objets java sont alloué au sein de la mémoire de la jvm. La jvm stocke cette mémoire dans un segment continu de mémoire système. Bien des des objets peuvent être désalloué dans la jvm (garbage collecting), le segment mémoire lui ne peut pas être diminué, et pour cause, il se pourrait qu'un objet "actif" se trouve toujours tout au bout du segment. On ne peut donc pas le diminuer. Pour pouvoir diminuer ce segment, il faudrait que la jvm implémente une politique de défragmentation de sa mémoire. Autant que je sache les expérience de sun dans ce domaine sont assez catastrophique (performances fortement dégradées de la jvm)

    Ce code te permettra de confirmer ce comportement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    package test;
    import java.util.*;
    import java.io.*;
    public class Test {
     
     
        public static void main(String[] args) throws Exception{
            BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
            Runtime.getRuntime().gc();
            System.out.println("Total memory: "+Runtime.getRuntime().totalMemory()+", free memory: "+Runtime.getRuntime().freeMemory()+", max memory: "+Runtime.getRuntime().maxMemory());
            System.out.println("Regardez la taille du process java. Puis tappez enter commencer l'allocation");
            r.readLine();
            System.out.println("Allocation de 700000 byte[] de 1k");
            List l = new ArrayList();
            for (int i=0; i< 700000; i++){
              if (i%10000==9999)
                 System.out.print(".");
              l.add(new byte[1024]);
            }
            System.out.println();
            byte[] b = new byte[1024];
            System.out.println("Total memory: "+Runtime.getRuntime().totalMemory()+", free memory: "+Runtime.getRuntime().freeMemory()+", max memory: "+Runtime.getRuntime().maxMemory());
            System.out.println("Regardez la taille du process java. Puis tappez enter pour vider la heap");
            r.readLine();
            l = null;
            Runtime.getRuntime().gc();
            System.out.println("Total memory: "+Runtime.getRuntime().totalMemory()+", free memory: "+Runtime.getRuntime().freeMemory()+", max memory: "+Runtime.getRuntime().maxMemory());
            System.out.println("Heap Videe, regardez si la taille du process java à diminué? Tappez enter pour quitter");
            r.readLine();
        }
    }
    Chez moi, au différentes étapes, çà donne ceci:
    delbd 9634 0.7 1.2 1195124 12580 pts/2 Sl+ 14:40 0:00 /usr/local/jdk1.6/bin/java -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=25 -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -Xmx1024m test.Test
    delbd 9634 7.1 72.5 1195740 750812 pts/2 Sl+ 14:40 0:07 /usr/local/jdk1.6/bin/java -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=25 -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -Xmx1024m test.Test
    delbd 9634 4.1 72.5 1195740 750808 pts/2 Sl+ 14:40 0:08 /usr/local/jdk1.6/bin/java -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=25 -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -Xmx1024m test.Test
    Soit au départ 12M, après allocation d'un gros paquet de donnée +-750M, après libération de ce gros bloc, +- 750M. La seule chose qui a diminué, je crois, c'est la mémoire système utilisée pour l'allocation de mémoire dans la jvm (soit qqes M par rapport au 700M de donnée libérées référencées par la jvm).

    Tu notera que le totalMemory() retourné par Runtime, ne diminue jamais.

  5. #5
    Membre Expert
    Avatar de natha
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 346
    Par défaut
    Je suis désolé de te contredire mais tu n'es pas tout à fait au clair avec le GC en Java et la gestion de la mémoire.

    Voici mon output après une mini-modification de ton code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ java -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=25 -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -Xmx1024m Test
    Total memory: 5177344, free memory: 5027936, max memory: 1065484288
    Regardez la taille du process java. Puis tappez enter commencer l'allocation
     
    Allocation de 700000 byte[] de 1k
    ......................................................................
    Total memory: 777986048, free memory: 42797368, max memory: 1065484288
    Regardez la taille du process java. Puis tappez enter pour vider la heap
     
    Total memory: 5181440, free memory: 5036048, max memory: 1065484288
    Heap Videe, regardez si la taille du process java à diminué? Tappez enter pour quitter
    J'ai transformé le dernier appel au GC comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            for (int i = 0; i < 20; i++) {
                Runtime.getRuntime().gc();
            }
    Voilà, une bonne lecture pour toi : http://gfx.developpez.com/tutoriel/java/gc/

    Je concluerais par : "Heureusement que la mémoire diminue pendant la vie du programme !!!"

  6. #6
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    +1 natha tu m'as devancé

    L'appel à gc() ne force pas le GC à libérer la mémoire, mais demande simplement au GC de "faire ses affaires" un peu plus tôt que prévu...


    En fait le GC ne libère pas immédiatement la mémoire au système, afin éventuellement la réutilisé sans avoir à la désallouer/réallouer : si ton application est amenée à utiliser beaucoup de mémoire il y a de forte chance que cela se reproduise assez rapidement.

    Si tu logges la boucle indiqué par natha tu verras qu'il faut environ 4 cycles du GC pour revenir à l'état initial :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Total memory: 778412032, free memory: 777388720, max memory: 1065484288
    Total memory: 701050880, free memory: 700118096, max memory: 1065484288
    Total memory: 422428672, free memory: 421823272, max memory: 1065484288
    Total memory: 5181440, free memory: 5054712, max memory: 1065484288

    Cette libération tardive permet de grosse amélioration des performances dans des traitements itératifs.

    Un exemple image une boucle de traitement qui utilise 200 Mo à chaque tours. Avec un GC "agressif" (qui libérerait la mémoire tout de suite) ou une gestion manuelle de la mémoire cela équivaut à allouer et libérer 200 Mo par itération.

    Avec le GC de Java on a une seule allocation de 200 Mo et éventuellement une seule libération à la fin du traitement. Le reste étant des manipulations en mémoire bien moins couteuse qu'une vrai allocation mémoire


    a++


    PS : Avec Java 5.0 on peut utiliser les MemoryMXBean pour un suivi plus fin que les méthode de Runtime...

Discussions similaires

  1. BufferedImage et accès plus direct aux pixels
    Par millie dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 09/01/2010, 10h40
  2. plus de ram ou bien le dual channel?
    Par wodel dans le forum Composants
    Réponses: 3
    Dernier message: 02/06/2008, 19h46
  3. [SQL + VB.NET] Alléger mon code pour un accès plus rapide
    Par Miles Raymond dans le forum VB.NET
    Réponses: 8
    Dernier message: 15/10/2007, 23h09
  4. J'voudrais mettre plus de RAM, mais ...
    Par angsthase dans le forum Composants
    Réponses: 4
    Dernier message: 23/09/2005, 22h38

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