4

.Jarファイルを実行できるようにしたいのですが、ヒープスペースが十分に大きく設定されていない場合は、同じ.Jarファイルで新しいJVMを起動しますが、より大きなヒープスペースで設定してから、最初のファイルを閉じます。 JVMと.Jar。

ProcessBuilderを使用してみましたが、動作させることができません。

クロスプラットフォームで動作する必要があります。

-鬼

4

4 に答える 4

6

私は解決策を見つけました、そしてそれはクロスプラットフォームで動作します。コードから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();
}
于 2011-05-20T23:20:08.220 に答える
1

初期ヒープサイズでJavaを起動し、必要な場合にのみ使用される最大ヒープサイズを指定することもできます。あなたが何をしようとしているのかわかりませんが、それはあなたが望む振る舞いをエミュレートするかもしれませんか?

java -Xms256m -Xmx1g -jar myapp.jar

この例では、256Mから開始します。アプリがより多くのメモリを必要とする場合は、1Gまで段階的に使用します。

于 2011-05-20T09:40:20.987 に答える
1

これら2つのソースを組み合わせてみてください。

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指定されたメモリサイズでaが開始されていることを確認します。

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);
        }
    }
}
于 2011-05-20T23:41:26.467 に答える
0

この種の作業は、外部スクリプトファイル(疑似コード)で行います。

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

OOMEをキャッチし、カスタムコードで終了することは常に可能であるはずです。このアプローチには1つの問題があります。$heap値がターゲットシステムで可能な最大ヒープスペース(例:Win32システムでは〜1.4GByte)を超えると、終了しません。

注:これは質問に対する単なる回答です-通常、大量のメモリを割り当てたり、メモリリークと戦ったりします-しかし、実際の要件/制限はわかりません

于 2011-05-20T09:39:49.000 に答える