Launch a large heap JVM

I want to be able to execute a .Jar file, and if the heap space is not set large enough, it should launch a new JVM with the same .Jar file but with a large heap size, and then close the first JVM and .Jar.

I tried to use ProcessBuilder, but I can't get it to work.

It should work with a cross platform.

-ONi

+3
source share
4 answers

I found a solution and it works cross platform. To restart the JVM from code, use the following. This answer is taken from another question that I found after several hours of searching here. If you want, you can monitor it with System.exit (0) to abort the JVM that started the new process after calling this method.

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(); } 
+6
source

You can run java with the initial heap size, and also specify the maximum heap size, which will be used only as needed. I'm not sure what you are trying to do, but can it emulate the behavior you need?

 java -Xms256m -Xmx1g -jar myapp.jar 

In this example, you start with 256M, if the application requires more memory, it will accept it, gradually, up to 1G.

+1
source

You can try combining these two sources.

MemoryRecoveryTest.java

Makes recovery attempts with 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

Runs the Process with the specified memory size.

 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); } } } 
+1
source

I would do such work in an external script file - in pseudocode:

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

Catch OOME and exit with custom code should always be possible. There is one problem with this approach - if the value of $ heap exceeds the maximum heap space that is possible for the target system (example: ~ 1.4GByte on Win32 systems), then it will not be completed.

Note: this is just the answer to the question - usually you need to assign a large amount of memory and / or deal with memory leaks, but I do not know these requirements / limitations

0
source

All Articles