重新启动 JVM,使用更大的堆空间

发布于 2024-11-08 15:01:31 字数 160 浏览 11 评论 0原文

我希望能够执行 .Jar 文件,如果堆空间设置得不够大,它应该启动一个具有相同 .Jar 文件的新 JVM,但设置更大的堆空间,然后关闭第一个JVM 和 .Jar。

我尝试过使用 ProcessBuilder,但无法让它工作。

它必须跨平台工作。

-ONi

I want to be able to execute the .Jar file, and if the heap space isn't set big enough, it should launch a new JVM with the same .Jar file, but set with a bigger heap space, and then close the first JVM and .Jar.

I've tried using the ProcessBuilder, but I can't get it to work.

It has to work cross platform.

-ONi

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

杀お生予夺 2024-11-15 15:01:31

我已经找到了解决方案,并且它可以跨平台工作。要从代码重新启动 JVM,请使用以下命令。这个答案取自我在此处搜索数小时后发现的另一个问题。如果需要,您可以在调用此方法后跟随 System.exit(0),以终止启动新进程的 JVM。

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

I have found the solution, and it works cross platform. To restart the JVM from code, use the following. This answer is taken from another question I found after hours of search in here. If you want, you can follow it with an System.exit(0), to terminate the JVM that started the new process, after a call to 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();
}
錯遇了你 2024-11-15 15:01:31

您可以使用初始堆大小启动 java,还可以指定仅在需要时使用的最大堆大小。我不确定你想做什么,但它可能会模仿你想要的行为?

java -Xms256m -Xmx1g -jar myapp.jar

在此示例中,您从 256M 开始,如果应用程序需要更多内存,它将逐渐增加,直到 1G。

You can launch java with an initial heap size, and also specify a maximum heap size which will be only be used as required. I'm not sure what you're trying to do but it might emulate the behaviour you want?

java -Xms256m -Xmx1g -jar myapp.jar

In this example you start with 256M, if the app needs more memory it will take it, incrementally, up until 1G.

琉璃梦幻 2024-11-15 15:01:31

您可以尝试将这两个来源结合起来。

MemoryRecoveryTest.java

尝试从 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

确保以指定的内存大小启动Process

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);
        }
    }
}

You might try combining these two sources.

MemoryRecoveryTest.java

Makes attempts to recover from an 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

Ensures a Process is started with a memory size specified.

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);
        }
    }
}
半夏半凉 2024-11-15 15:01:31

我会在外部脚本文件中执行此类工作 - 使用伪代码:

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

捕获 OOME 并使用自定义代码退出应该始终是可能的。这种方法有一个问题 - 如果 $heap 值超过目标系统可能的最大堆空间(例如:Win32 系统上的 ~1.4GByte),那么它将不会终止。

注意:这只是问题的答案 - 通常人们会分配大量内存和/或解决内存泄漏 - 但我不知道实际的要求/限制

I'd do this kind of work in an outer script file - in pseudo code:

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

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

Note: this is just an answer to the question - usually one would assign a high amount of memory and/or fight the memory leaks - but I don't know the actual requirments/restrictions

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文