Memoire de la machine virtuelle

estetzein Messages postés 8 Date d'inscription lundi 20 janvier 2003 Statut Membre Dernière intervention 7 septembre 2004 - 6 sept. 2004 à 15:11
desastreux Messages postés 50 Date d'inscription mardi 30 mars 2004 Statut Membre Dernière intervention 5 août 2009 - 2 déc. 2004 à 10:08
Bonjour,

Voila, j'aimerai pouvoir dire a ma machine virtuelle quelle taille mémoire allouer lorsque je lanc emon application. Pour le moment je fais cette allocation en lancant mon programme avec un ficiher batch comme ceci : @java -jar -Xmx1300m SLB01.jar

Ce que je voudrais, c'est créer un executable avec dedans l'allocation de mémoire voulue.

si vous avez une idée, n'hésitez pas. Merci d'avance.

-:: Estetzein ::-

8 réponses

cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
6 sept. 2004 à 23:04
GodConan :clown)

et bien deja en java tu ne creer pas vraiment d executable !!!

et durant l execution d une appli java ce n est pas toujour simple de predir la place dont elle aura besoin ... ca depand beaucoup de la gestion de la JVM....

donc je ne vois pas de soluce sorry

++
0
estetzein Messages postés 8 Date d'inscription lundi 20 janvier 2003 Statut Membre Dernière intervention 7 septembre 2004
7 sept. 2004 à 10:06
Ok, je vois. Mais admettons qu'on sache que l'aura besoin de 150Mo au lieu des 64Mo allouer par defaut. Comment fait-on ?

-:: Estetzein ::-
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
7 sept. 2004 à 13:05
GodConan :clown)

kel version de java utilise tu ? car avec 1.4 je n est pas ce genre de problem !!
0
estetzein Messages postés 8 Date d'inscription lundi 20 janvier 2003 Statut Membre Dernière intervention 7 septembre 2004
7 sept. 2004 à 14:26
Ok, mio j'utilise aussi la version 1.4 Ms lorsque je charge mes fichiers XML (plusieurs 10aines de Mo) on depasse vite fait les 64Mo alloué de base.

Donc je fais ce -Xmx500Mo par exmple dans la ligne de commande. Ms je voudrais le faire en dur... dans le prog, comme ca pas besoin de passser par un batch pr lancer l'appli...

-:: Estetzein ::-
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
7 sept. 2004 à 14:55
GodConan :clown)

hmm je ne te suis pas trop!! Mais bon si tu veu faire comme moi un exe ki lance un jar ou un .class tu peu ds ton prog C++ (par exemple) metre exactement la meme command que ds ton batch
puisque c une obtion de java ou javaw ;o) et c est bien toujour la jvm qui fera la reservation memoire ... logic puisque c est elle qui en a besoin...
0
desastreux Messages postés 50 Date d'inscription mardi 30 mars 2004 Statut Membre Dernière intervention 5 août 2009
15 nov. 2004 à 13:46
Je rencontre le même soucis que estetzein et le problème me semble pourtant plutôt clair :

Lors de traitement de gros fichiers ( même avec l'utilisation des nouvelles classes de java.nIO.*, bien plus performantes que celles de java.IO.* ) on obtient assez vite un dépassement de la heap-size de la JVM, pauvrement limitée par défaut à 64Mo...

La possibilité de modifier cette allocation par défaut existe heureusement, cependant, elle semble devoir être nécéssairement lancée en mode console, ou depuis un BATCH ( fichier de commande MS-DOS ) ou bien encore depuis une autre class qui va appeller notre class de base (ici "toto.jar") en utilisant :

Process p = new Process();
p = runtime.getRuntime().exec("java -Xms128m -Xmx512m - jar toto.jar");

Par contre, il semble impossible de modifier la HEAP-size de la JVM directement depuis l'application qu'elle vient de lancer.
On ne peut pas appeller "toto.jar" depuis "toto.jar" avec le code ci-dessus...

J'ai pour ma part essayé d'inclure mon "toto.jar" dans une autre archive JAR dont la class principale contient le batch-code ci-dessus de sorte de ne se retrouver qu'avec une seule application JAR ( et non un launcher + l'appli...) . En vain.

Autre problème : Pour faire une allocation automatique d'un maximum de RAM à la JVM, il faut conaitre la RAM dont dispose le système. Un dépassement provoque en effet une erreur de la JVM. Hors, je n'arrive pas à trouver de renseignements sur la façon de récupérer cette valeur avec JAVA.

On peut en effet récupérer la RAM allouée à la JVM en cours de programme ( runtime.getRuntime().maxMemory ) mais pour ce qui est celle du système ? ( Même un language débile (oups!) comme Visual Basic le propose pourtant ...!!! )

Bref, je serais particulièrement heureux qu'une âme charitable et savante veuille bien se préoccuper de ce petit problème particulièrement gênant...

:shy)
0
desastreux Messages postés 50 Date d'inscription mardi 30 mars 2004 Statut Membre Dernière intervention 5 août 2009
16 nov. 2004 à 12:49
Tiens : Je me réponds (un peu) à moi même (:Fabuleux !)
J'ai dit une (toute) petite bêtise ci-dessus.
En effet, j'ai réussi à compiler une appli JAR qui demande à son lancement la quantité de RAM à allouer à la JVM pour sa propre éxécution... L'astuce ?

Ben la réponse était (comme souvent) contenue dans mes à prioris foireux :
Voilà, la première fois, je vérifie que la RAM allouée est bien inférieure à 64Mo (c'est la quantité minimale dont j'ai besoin) et je propose un jSlider à l'utilisateur pour l'augmenter d'au moins 1Mo ( Par défaut jusqu'à 1Giga5 puisque malgré pleins de tests avec captures d'exceptions, je ne parviens toujours pas à déterminer via le code JAVA la quantité de RAM présente sur le hardWare : Ce qui implique malheureusement une potentielle erreur de lancement de la JVM : Au secours !?! )

Bref, l'application peut bien se relancer elle-même, avec les nouveaux paramètres, puisqu'une fois relancée, n'étant plus en-dessous du seuil de pauvreté (les 64Mo pour les distraits) elle n'a plus besoin de proposer à l'utilisateur le jSlider et peut désormais s'éxécuter en toute tranquilité avec les paramètres choisis par l'utilsateur. ( Implique toutefois un double-chargement un peu lourd... )

De manière plus générale, on aurait pu laisser à l'utilisateur la possibilité de relancer l'appli ou non depuis un jSlider systématiquement lancé au début ( En cas de CANCEL, l'appli continuerait alors à s'éxécuter avec les paramètres en cours... )

Je crois que cela est une réponse pas trés élégante, mais valable, à la question du Topic ( Elle est de plus certes un peu longue, et en plusieurs fois, mais je suis un newbie et vous connaissez le proverbe : "Tirez pas sur le newbie !" )

Avant de me retirer, je me permets toutefois de reposer la question subsidiaire pour ne pas que le débat soit clos trop tôt :
(Et parce que je n'en peux plus de chercher ! )
Pour proposer une valeur MAX de RAM à allouer à la JVM par l'utilisateur, il serait utile de pouvoir récupérer la RAM max présente sur le système, mais comment ?
0
desastreux Messages postés 50 Date d'inscription mardi 30 mars 2004 Statut Membre Dernière intervention 5 août 2009
2 déc. 2004 à 10:08
Bon, bon, si vous avez été malin, vous avez sauté le roman fleuve pour arriver directement à la réponse ci-dessous :
Ce code permets donc de modifier à la demande de l'utilisateur, la RAM à allouer à la JVM pour les CLASS suivantes d'une même archive JAR, et permets en plus de déterminer la RAM présente sur le système pour proposer un MAX pertinent :
(Rappellez-vous que cela ne marchera pas pour une APPLET non signée ! )

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class untitled {

JFrame frame = new JFrame(" Launcher RAM / JVM ");
JPanel ihm = new JPanel();
JSlider jSlider1 = new JSlider();
JLabel infoRAM = new JLabel();
JButton jButton1 = new JButton();
static int Mb = 1048760;
static int sysRam;
JLabel jLabel1 = new JLabel();

public static void main(String[] args)
{ // On va tester la RAM max présente sur le système CLIENT ( Ici à partir de 1792 Mo, en diminuant : )
sysRam = 1792;
if (args.length < 1) // Pas d'argument lorsque cette CLASSS a été lancée (premier lancement)
{
try
{
Process processus;
String batchC;
do
{
System.out.println("Chargement du test d'émulation à : " + sysRam + " Mo.");
batchC = "java -Xms" + ( (int) ( (Runtime.getRuntime().maxMemory() - Runtime.getRuntime().freeMemory()) / Mb)) +
"m -Xmx" + sysRam + "m -jar monArchiveAvecMonAppliEtCetteCLASSenManifest.jar ramTEST";
processus = Runtime.getRuntime().exec(batchC);
try { int endProc = processus.waitFor(); }
catch (java.lang.InterruptedException itrptE) {}
System.out.println("Etude du test d'émulation à : " + sysRam + " Mo / términé ! Erreur Code = " + processus.exitValue());
sysRam -= 64; // On va tester en diminuant de 64 Mo à chaque fois jusqu'à obtenir le MAX voulu
}
while ( (processus.exitValue() != 0) && (sysRam > 64));
if (processus.exitValue() == 0)
{ // Valeur MAX trouvée : On relance notre appli avec cette valeur/JVM ( à titre de TEST )
batchC = "java -jar monArchiveAvecMonAppliEtCetteCLASSenManifest.jar " + (sysRam + 64);
processus = Runtime.getRuntime().exec(batchC);
System.out.println(processus);
}
System.exit(0);
}
catch (java.io.IOException e2) { System.out.println(e2); }
}
else if ( (args[0].compareTo("ramOK") != 0) && (args[0].compareTo("ramTEST") != 0))
{ // L'argument passé en paramètre lorsque cette CLASS se relance déterminera le constructeur...
sysRam = (Integer.valueOf(args[0])).intValue();
RAMtester toto = new RAMtester(false);
} // ( Voir ci-dessous ) Pour savoir s'il faut ou non proposer à l'utilisateur de changer la RAM.
else if (args[0].compareTo("ramOK") == 0)
{ RAMtester toto = new RAMtester(true); }
else if (args[0].compareTo("ramTEST") == 0)
{
System.out.println("TEST d'émulation en cours...");
System.exit(0);
}
}

public RAMtester(boolean okay)
{ // Constructeur :
if (!okay)
{ // L'objet est construit avec un booléen qui lui signifie...
try { jbInit();}
catch (java.lang.Exception jle) {}
} // ...S'il faut proposer à l'utilisateur de changer la RAM...
else if (okay)
{ // ... Ou bien de lancer la CLASS voulue, avec la RAM actuelle :
String[] rien = {"", ""};
maCLASSappli = new maCLASSapli(); // ça y'est !
try { this.finalize(); }
catch (java.lang.Throwable th) {}
} // Cette RAM actuelle a été obtenue grâce à la récursivité de celle-ci :
}

public void jbInit() throws Exception
{ // I.H.M. pour choisir la RAM à allouer à la JVM :
jSlider1.setMaximum(sysRam);
jSlider1.setMinimum( ( (int) ( (Runtime.getRuntime().maxMemory() - Runtime.getRuntime().freeMemory()) / Mb)));
jSlider1.setValue(sysRam/2);
jSlider1.addChangeListener(new RAMtester_jSlider1_changeAdapter(this));
jSlider1.setSize(430, 25);
jSlider1.setLocation(25, 50);
infoRAM.setBounds(new Rectangle(25, 25, 430, 25));
infoRAM.setFont(new java.awt.Font("Comic Sans MS", 1, 20));
infoRAM.setHorizontalAlignment(SwingConstants.CENTER);
infoRAM.setForeground(new Color(0, 0, 102));
infoRAM.setBorder(BorderFactory.createRaisedBevelBorder());
infoRAM.setBackground(new Color(100, 200, 200));
infoRAM.setText("RAM à allouer : " + String.valueOf(jSlider1.getValue()) + " Mo");
infoRAM.setOpaque(true);
ihm.setLayout(null);
jButton1.setBounds(new Rectangle(278, 267, 109, 25));
jButton1.setText("OK");
jButton1.addActionListener(new RAMtester_jButton1_actionAdapter(this));
jLabel1.setBackground(new Color(100, 230, 210));
jLabel1.setForeground(Color.darkGray);
jLabel1.setBorder(BorderFactory.createRaisedBevelBorder());
jLabel1.setOpaque(true);
jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
jLabel1.setHorizontalTextPosition(SwingConstants.CENTER);
jLabel1.setText("Mo");
jLabel1.setBounds(new Rectangle(421, 170, 33, 27));
ihm.add(jSlider1, null);
ihm.add(infoRAM, null);
ihm.add(jLabel1, null);
ihm.add(jButton1, null);
ihm.add(jLabel3, null);
frame.getContentPane().add(ihm, BorderLayout.CENTER);
Dimension d = new java.awt.Dimension(480, 300);
ihm.setPreferredSize(d);
ihm.setBackground(new Color(20, 20, 102));
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}

void jSlider1_stateChanged(ChangeEvent e)
{ infoRAM.setText("RAM à allouer /JVM : " + String.valueOf(jSlider1.getValue()) + " Mo"); }

void jButton1_actionPerformed(ActionEvent e)
{ // L'utilisateur a choisi la RAM et fait OK :
try
{
System.out.println("Veuillez attendre SVP : L'application doit se relancer avec les nouveaux paramètres d'allocation de RAM/JVM");
String batchC = "java -Xms" +
( (int) ( (Runtime.getRuntime().maxMemory() - Runtime.getRuntime().freeMemory()) / Mb)) + "m -Xmx" +
jSlider1.getValue() + "m -jar loaderDXF.jar ramOK";
Process processus = Runtime.getRuntime().exec(batchC);
System.exit(0);
}
catch (java.io.IOException e2) { System.out.println(e2); }
}
}

class RAMtester_jSlider1_changeAdapter
implements javax.swing.event.ChangeListener
{// LISTENER pour le SLIDER
RAMtester adaptee;
RAMtester_jSlider1_changeAdapter(RAMtester adaptee) {
this.adaptee = adaptee;
}
public void stateChanged(ChangeEvent e) {
adaptee.jSlider1_stateChanged(e);
}
}

class RAMtester_jButton1_actionAdapter
implements java.awt.event.ActionListener
{// LISTENER pour le bouton de validation
RAMtester adaptee;
RAMtester_jButton1_actionAdapter(RAMtester adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.jButton1_actionPerformed(e);
}
}
0
Rejoignez-nous