java jvm heap reboot relaunch

java - Relanzar JVM con mayor espacio de almacenamiento



heap reboot (4)

Quiero poder ejecutar el archivo .Jar, y si el espacio del montón no está configurado lo suficientemente grande, debería iniciar una nueva JVM con el mismo archivo .Jar, pero establecer con un espacio de montón más grande, y luego cerrar el primero JVM y .Jar.

Intenté usar ProcessBuilder, pero no puedo hacer que funcione.

Tiene que funcionar multiplataforma.

-ONI


Encontré la solución y funciona en varias plataformas. Para reiniciar la JVM desde el código, use lo siguiente. Esta respuesta proviene de otra pregunta que encontré después de horas de búsqueda aquí. Si lo desea, puede seguirlo con un System.exit (0) para finalizar la JVM que inició el nuevo proceso, después de una llamada a este método.

public static void startSecondJVM() throws Exception { String separator = System.getProperty("file.separator"); String classpath = System.getProperty("java.class.path"); String path = System.getProperty("java.home") + separator + "bin" + separator + "java"; ProcessBuilder processBuilder = new ProcessBuilder(path, "-Xmx1024m", "-cp", classpath, Main.class.getName()); Process process = processBuilder.start(); }


Haría este tipo de trabajo en un archivo de script externo, en pseudo código:

$heap := 128 $ok := true do { exitCode = java -Xmx$heapM -jar myApp.jar if (exitCode = OOME) { heap += 128 $ok := false } while(!$ok)

Capturar OOME y salir con un código personalizado siempre debería ser posible. Hay un problema con este enfoque: si el valor de $ heap excede el espacio de almacenamiento dinámico máximo que es posible para el sistema de destino (ejemplo: ~ 1.4 GB en sistemas Win32), no finalizará.

Nota: esta es solo una respuesta a la pregunta: por lo general, uno asignaría una gran cantidad de memoria y / o lucharía contra las fugas de memoria, pero no conozco los requisitos / restricciones reales.


Puede iniciar Java con un tamaño de almacenamiento dinámico inicial y también especificar un tamaño de almacenamiento dinámico máximo que solo se usará según sea necesario. No estoy seguro de lo que estás tratando de hacer, pero podría emular el comportamiento que deseas?

java -Xms256m -Xmx1g -jar myapp.jar

En este ejemplo, comienza con 256M, si la aplicación necesita más memoria, la llevará, de forma incremental, hasta 1G.


Puede intentar combinar estas dos fuentes.

MemoryRecoveryTest.java

Intenta recuperarse de un OutOfMemoryError .

/*License - LGPL <h3>Recovery from an OutOfMemory Error</h3> <p>The JavaDocs for Error state, in the first sentence.. <blockquote>"An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."</blockquote> <p>This advice has led to the fallacy that an OutOfMemoryError should not be caught and dealt with.But this demo. shows that it is quite easy to recover to the point of providing the user with meaningful information, and advice on how to proceed. <p>I aim to make my applications ''unreasonable''.;-) */ import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JPanel; import javax.swing.JLabel; import javax.swing.JProgressBar; import javax.swing.JOptionPane; import javax.swing.JDialog; import javax.swing.Timer; import javax.swing.border.EmptyBorder; import java.util.ArrayList; /** A demo. showing recovery from an OutOfMemoryError. Our options once an OOME is encountered are relatively few, but we can still warn the end user and provide advice on how to correct the problem. @author Andrew Thompson */ public class MemoryRecoveryTest { public static void main(String[] args) { // reserve a buffer of memory byte[] buffer = new byte[2^10]; ArrayList<Object> list = new ArrayList<Object>(); final JProgressBar memory = new JProgressBar( 0, (int)Runtime.getRuntime().totalMemory()); ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { memory.setValue( (int)Runtime.getRuntime().freeMemory() ); } }; Timer timer = new Timer(500, listener); timer.start(); JDialog dialog = new JDialog(); dialog.setTitle("Available Memory"); JPanel memoryPanel = new JPanel(); memoryPanel.add(memory); memoryPanel.setBorder(new EmptyBorder(25,25,25,25)); dialog.add( memoryPanel ); dialog.pack(); dialog.setLocationRelativeTo(null); dialog.setVisible(true); dialog.addWindowListener( new WindowAdapter(){ @Override public void windowClosing(WindowEvent we) { System.exit(0); } } ); // prepare a memory warning panel in advance JPanel memoryWarning = new JPanel(); memoryWarning.add( new JLabel( "<HTML><BODY>There is not enough memory to" + " complete the task!<BR> Use a variant " + " of the application that assigns more memory.") ); try { // do our ''memory intensive'' task while(true) { list.add( new Object() ); } } catch(OutOfMemoryError oome) { // provide the VM with some memory ''breathing space'' // by clearing the buffer buffer = null; // tell the user what went wrong, and how to fix it JOptionPane.showMessageDialog( dialog, memoryWarning, "Out of Memory!", JOptionPane.ERROR_MESSAGE); } } }

IWantToBeBig.java

Asegura que un Process se inicie con un tamaño de memoria especificado.

import java.awt.EventQueue; import javax.swing.JOptionPane; import java.io.File; class IWantToBeBig { public static void main(String[] args) throws Exception { if (args.length==0) { ProcessBuilder pb = new ProcessBuilder( "java", "-jar", "-Xmx512m", "big.jar", "anArgument" ); pb.directory(new File(".")); Process process = pb.start(); process.waitFor(); System.out.println("Exit value: " + process.exitValue()); } else { Runnable r = new Runnable() { public void run() { JOptionPane.showMessageDialog( null, "Max Memory: " + Runtime.getRuntime().maxMemory() + " bytes."); } }; EventQueue.invokeLater(r); } } }