Je répondais juste a ton interrogation sur l'utilisation mémoire "réelle" du processus de la JVM par rapport aux options Xms et Xmx.
Xms est la mémoire utilisée dés le démarrage.
Xmx est la mémoire allouée mais pas forcement utilisée pour l'instant.
Les variations de la mémoire utilisée en fonction des allocations du programme Java n'ont rien d'extraordinaire: Plus tu crées des instances d'objets, plus la mémoire utilisée augmente. Quand les objets ne sont plus utilisés, la mémoire est liberée a chaque cycle d'execution du GC. Le démarrage d'un cycle est parametrable par d'autres options de la JVM (cf liens précédants).
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Non, enfin pas a ma connaissance. Java et C++ sont des langages différents et c'est tant mieux. Si tu créés une appli pour laquelle la gestion de la mémoire est vraiment crucial, alors utilises C++, lol. Maintenant pour la plupart des applications, graphique ou web, java est parfaitement adapté et si ton code est bien fait, cela ne consomera pas plus, ou ne sera pas plus lent que la même appli en C++. Pour moi le seul avantage que je vois à C++ c'est que l'on accés au hardware de la machine, c a d que l'on peut programmer à un bas niveau, et encore pour ce genre de programme je préfererai faire toute les taches de bas niveau en C, et ensuite couplé sa a du JNI.
Juste une petite nuance : Xmx correspond à la quantité maximum de mémoire allouable par le programme, mais ce n'est pas pour autant que cette quantité sera utilisé...
Pour une application Java en théorie l'OS c'est la machine virtuelle
Par contre je suis d'accord que cette notion de taille maximum puisse être problématique dans certain cas puisqu'il faut la définir explicitement. Quoique cela peut dépendre aussi de la JVM (il me semble que par défaut la JVM d'IBM s'adapte au système pour cette valeur).
C'est déjà ce que fait le Garbage Collector : il alloue la mémoire d'un bloc
Surement pas... mais je dois t'avouer que dans mon domaine (application de gestion & serveur d'application) je n'ai jamais eu à toucher à cela, que ce soit en Java ou en C (concrètement je ne sais même pas quel en est l'utilité).
As-tu au moins jeter un coup d'oeil sur les liens qui t'ont été donné ? Xms et Xmx correspondent simplement aux options de base...
Comme je l'ai dit le Xmx est la valeur maximale, mais si l'application consomme moins de mémoire elle ne sera bien évidemment pas atteinte.
Bien sur si tu utilises Xms avec 200 Mo alors ton application consommera 200 Mo même si elle n'en a pas besoin, mais c'est une erreur de ta part et non pas du système (ce serait comme si tu allouais 200 Mo de mémoire en C/C++ sans les utiliser).
Non je n'ai jamais vraiment eu de besoin si spécifique que cela. Le comportement par défaut du GC est tout à fait correct pour mes besoins.
C'est à dire concrètement ? Pourrais-tu donner un exemple du code que tu as modifié ?
a++
le fond du probleme est que à chaque fois qu'on dit que le garbage est embetant car il ne libere pas assez vite la memoire et que le processus se met a consommer de la memoire a fond de 5ieme, alors on nous dit que le GC se parametre !!!
montrez ou citez moi un exemple concret dans lequel ca a marché !
et quelles options vous avez utilisées ? et comment le programme a reagit ?
c'est trop compliqué ?
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
oui je peux. Je l'avais deja expliqué d'ailleurs.
j'avais une boucle dans lequel je recreais une String assez grosse.
Le programme utilisait de la memoire à atteindre les limites (256Mo) et plantait.
ca parait simple dit comme ca non ? mais imaginez donc que cette string etait enfoui dans la structure de données manipulée...
c'etait pas facile mais apres de nombreuses tentatives sur le parametrage du GC et de revus de code alors je m'en suis apercu, et j'ai utilisé un StringBuffer que j'ai ensuite propagé dans ma structure. resultat: le programme utilise 40Mo
bon ...
franchement je pensais avoir été assez clair.
j'ai une boucle (for ou while) dans laquelle a chaque tour, une String très grosse était créée (le resultat d'un StringBuffer)
c'est bon jusque la ? je fais donc de l'allocation assez consequente a chaque tour de boucle en gros ...
Cette allocation etait faite tres enfouite profondemment dans ma structure de données ok ?
ca faisait exploser le processus ( > 256Mo)
J'ai du modifier mon code pour creer un stringBuffer avant la boucle puis a chaque tour de boucle, la passer a ma structure de données pour qu'elle puisse reutiliser la StringBuffer plutot que d'en refaire un.
au final l'appli ne prend plus que 40 Mo
l'allocation faite a chaque tour de boucle varie en fait...
ca peut etre 2Ko, 200Ko, 2Mo
maximum 3Mo
le nombre de tour de boucle est cependant important (>6000)
C'est faux! L'experience montre que Java s'etend tout doucement jusqu'a atteindre la limite fixée (par defaut a 64 Mo).
euh, ben oui, mais la bon...
si tu alloue une grosse String dans une boucle.. ben, pas de miracle, tu bouffes de la memoire
tu peux meme descendre au niveau bytebuffer ou charbuffer en java pour faire des trucs de ce genre avec de hautes performances
n'oubliez pas que ce n'est pas si evident que cela, si tout est bien encapsulé ...
n'oubliez pas que meme une lib que vous utilisez peut faire une allocation de ce type.
enfin le GC se configure non ?
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Oui enfin, c'est quand même un piège classique parce que: la string est immutable d'une part, et que les instanciation sont masquées par les opérateurs d'une autre.
Donc quand on fait un s+=<nimporte quoi> dans une boucle, on a à chaque fois la conversion de String en stringbuffer pour l'ajout (le compilo qui transforme le +=), puis la recréation d'une String.
on crée plein d'objets destinés à être supprimés ensuite, on fait travailler le GC pour rien.
Le problème serait le même avec d'autres objets immutable (Double, BigInteger...) dont on veut une valeur modifée à chaque tour de boucle: on crée des objets à tour de bras.
il faut penser les conceptions en minimisant les créations d'objet temporaire (de même qu'en C++ du reste)
parce que tu penses que tu peux toujours penser cela a la conception ?
... tu te trompes
et en C++ cela n'aurait pas été génant, au niveau de la memoire il serait resté à ras le sol
Je parlait de conception de classe immutable type String, il faut prévoir son pendant type StringBuffer mutable à la conception des diagrammes de classe.
Maintenant, si je me trompe, c'est peut-être parce que tout le monde code avant les conceptions
Pour l'utilisation des string-stringbuffer, c'est juste une habitude de réalisation. Le problème ne se pose pas sur les String en C++ vu que ça ne fonctionne pas du tout pareil, mais dans n'importe quel langage, allouer-désallouer de la mémoire en permanence dans des boucles, c'est mal.
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
ou peut-etre que tu oublies les changements de derniere minute, un budget à respecter, les differences entre les programmeurs, et que les details d'implementation sont rarement abordés à la conception.
en plus, comme j'ai déjà dit, tu pourras utiliser une lib qui elle meme fait une allocation de ce type, et que si tu l'utilises dans une boucle, tu auras le meme probleme.
montrez moi que ces details d'implementations peuvent etre gommés en configurant le GC, a chaque fois on me le ressort alors j'attends maintenant en fait !
Aussi arretez de trouver toujours des excuses, un coup c'est la config du GC, un autre coup, c'est la conception... bof !
l'excuse de la conception, je peux le ressortir a chaque critique.... c'est nul!
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Le GC ne permet pas de gommer des problèmes d'implémentations mais seulement de gérer la mémoire...
Et des problèmes d'implémentations tu peux tout aussi bien en avoir en C++ en gérant la mémoire à la main !
On ne cherche pas d'excuse : on ignore toujours le code qui est en cause ! Et tu as dit toi même que tu as dû changer l'implémentation donc on en déduit que la première n'était pas bonne...
C'est toi qui affirme depuis le début que le problème vient du GC !
a++
tu confonds probleme d'implementation et detail d'implementation
avec Java, tu as le GC mais en fait on est quand meme obligé de la gerer a la main, alors oui pour moi le GC n'est pas assez performant.
ne confond pas non plus avec le C++, un probleme de pointeur n'est pas la meme chose. Dans mon cas le programme Java fonctionnait mais prenait trop de memoire. Desolé tu ne peux pas avoir cela en C++.
au fait partant de cela, tous les problemes memoires vont finir par nous faire modifier le code puisque la configuration du GC n'y pourra jamais rien
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager