web-dev-qa-db-fra.com

Comment définir le -Xmx lorsque vous démarrez un fichier jar?

Comme nous savons que nous pouvons définir -Xmx1024M dans window->preferences->Java->installed jres->edit->default vm arguments dans Eclipse . Mais lorsque je compresse ce projet dans un fichier jar exécutable, comment puis-je définir le -Xmx1024M lors de l'exécution du jar via Java -jar A.jar?

Merci beaucoup!

28
Judking

Malheureusement, les réponses existantes sont fausses sur un point crucial. 

-Xmx doit être transmis à l'environnement d'exécution Java, pas au fichier jar exécuté.

Faux:

Java -jar JavaApplication.jar -Xmx1024m 

Correct:

Java -Xmx1024m -jar JavaApplication.jar 

Plus spécifiquement, le Java Launcher doit être utilisé comme suit:

Java [options] -jar fichier.jar [arguments]

  • [options] sont passés à l'environnement d'exécution Java
  • [arguments] sont passés à la fonction principale

Le paramètre -Xmx appartient aux options (non standard) de la machine virtuelle Java et doit être répertorié avant -jar (ou au moins avant fichier.jar). La JVM ne reconnaîtra pas un argument -Xmx transmis à la fonction principale comme proposé dans d'autres réponses.

89
Philipp Merkle

Trois méthodes:

  • Ligne de commande:
    • Demandez à vos utilisateurs d'exécuter votre application en utilisant "Java -jar SampleJavaApp.jar -Xmx1024m"
  • Panneau de configuration Java:
    • Demandez à vos utilisateurs de consacrer plus de mémoire à Java par défaut: Guide Win7
  • Redémarrez votre jar avec la valeur Xmx appropriée.

La dernière option est "diabolique" mais ne nécessite aucun effort supplémentaire de la part de vos utilisateurs. Voici un exemple de bloc de code:

public static void main(String[] args) throws IOException, URISyntaxException {
    String currentPath=SampleJavaApp.class
          .getProtectionDomain()
          .getCodeSource().getLocation()
          .toURI().getPath()
          .replace('/', File.separator.charAt(0)).substring(1);
    if(args.length==0 && Runtime.getRuntime().maxMemory()/1024/1024<980) {
        Runtime.getRuntime().exec("Java -jar -Xmx1024m "+currentPath+" restart");
        return;
    }
}
6
user1361991

user1361991> J'aime votre option diabolique mais je ne peux pas la commenter car je suis encore novice ici. Quoi qu’il en soit, j’ai pensé que cela méritait un peu d’amélioration car je trouve que la redirection stderr et stdout manque.

String currentPath= MyClass.class
    .getProtectionDomain()
    .getCodeSource().getLocation()
    .toURI().getPath()
    .replace('/', File.separatorChar).substring(1) ;
if ( args.length == 0 && Runtime.getRuntime().maxMemory()<512*1024*1024) {
    Process p= Runtime.getRuntime().exec("Java -jar -Xmx512M " + currentPath + " restart") ;
    new StreamGobbler(p.getInputStream()).start() ;
    new StreamGobbler(p.getErrorStream()).start() ;
    p.waitFor() ;
    return ;
}

et la source StreamGobbler (probablement extraite quelque part d’Internet pour être honnête et modifiée un peu, je ne me souviens plus):

public class StreamGobbler
    extends Thread
{
    public StreamGobbler( InputStream is )
    {
        this(is, System.out) ;
    }

    public StreamGobbler( InputStream is, PrintStream ps )
    {
        this.is= is ;
        this.ps= ps ;
    }
    private final InputStream is ;
    private final PrintStream ps ;

    @Override
    public void run()
    {
        try {
            InputStreamReader isr= new InputStreamReader(is) ;
            BufferedReader br= new BufferedReader(isr) ;
            for ( String line ; (line= br.readLine()) != null ; ) {
                ps.println(line) ;
            }
       }
       catch ( IOException ioe ) {
           ioe.printStackTrace() ;
       }
    }
}
0
user4599075