.Jarファイルを実行できるようにしたいのですが、ヒープスペースが十分に大きく設定されていない場合は、同じ.Jarファイルで新しいJVMを起動しますが、より大きなヒープスペースで設定してから、最初のファイルを閉じます。 JVMと.Jar。
ProcessBuilderを使用してみましたが、動作させることができません。
クロスプラットフォームで動作する必要があります。
-鬼
.Jarファイルを実行できるようにしたいのですが、ヒープスペースが十分に大きく設定されていない場合は、同じ.Jarファイルで新しいJVMを起動しますが、より大きなヒープスペースで設定してから、最初のファイルを閉じます。 JVMと.Jar。
ProcessBuilderを使用してみましたが、動作させることができません。
クロスプラットフォームで動作する必要があります。
-鬼
私は解決策を見つけました、そしてそれはクロスプラットフォームで動作します。コードから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();
}
初期ヒープサイズでJavaを起動し、必要な場合にのみ使用される最大ヒープサイズを指定することもできます。あなたが何をしようとしているのかわかりませんが、それはあなたが望む振る舞いをエミュレートするかもしれませんか?
java -Xms256m -Xmx1g -jar myapp.jar
この例では、256Mから開始します。アプリがより多くのメモリを必要とする場合は、1Gまで段階的に使用します。
これら2つのソースを組み合わせてみてください。
からの回復を試み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);
}
}
}
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);
}
}
}
この種の作業は、外部スクリプトファイル(疑似コード)で行います。
$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)を超えると、終了しません。
注:これは質問に対する単なる回答です-通常、大量のメモリを割り当てたり、メモリリークと戦ったりします-しかし、実際の要件/制限はわかりません