プログラムの 1 つをスタンドアロン Java アプリケーションから Java アプレットに移植しました。アプリケーションは大きな画像ファイルを処理するため、より多くのヒープ領域が必要になるため、それらをメモリにロードします。画像は、JOGL を使用した openGL ウィンドウでテクスチャ データとして使用されます。
アプリケーションは、Eclipse 内で (アプレットとしてもスタンドアロンとしても) 正常に動作し、スタンドアロン アプリケーションを実行可能 jar としてエクスポートすると、正常に動作します。これをさまざまなシステムでテストしました (Windows XP 32 で 4 GB RAM、Windows XP 64 で 12 GB RAM、および Windows 7 64 ビットで 4 GB および 8 GB RAM)。
プログラムのアプレット バージョンをエクスポートすると、問題が発生します。jar に署名し、ブラウザ (テスト済みの Firefox および IE) で実行しようとした後、上記の 64 ビット マシンではアプリケーションが常に OutOfMemory 例外でクラッシュします。
Windows XP 32ビットマシンでは、少しいじった後に機能しましたが、さまざまなソリューションを試すだけで、以前の試行でクラッシュにつながったとしても、そのうちの1つが機能したため、理由はわかりません。
ヒープスペースを増やそうとした4つの方法があります
私が試したhtmlファイルで:
<PARAM name="java_arguments" value="-Xmx1600m">
うまくいきませんでした。
次に、-Xmx1600M 引数を使用して、Java メニュー ([スタート] -> [コントロール パネル] -> [Java] タブ -> [Java ランタイム環境の設定]) からヒープを直接増やしてみました。この帽子もインパクトなし。
その後、Jogamp の担当者から提供された jnlp ファイルを使用しました。そこに追加しました
<j2se version="1.6+" java-vm-args="-Xmx1600m"
href="http://java.sun.com/products/autodl/j2se"/>
リソースタグ内。これも最初は効果がありませんでした。
最後に追加しました
<j2se version="1.6+" initial-heap-size="256M" max-heap-size="1600M"
href="http://java.sun.com/products/autodl/j2se"/>
リソースタグ内で、何とか数回試行した後、4つの異なるソリューションを一周し、機能したアプレットキャッシュをクリアしました(ただし、32ビットWinXPマシンのみ)。
しかし、私は 64 ビット マシンでアプレットを実行しようとしても成功しませんでした。いくつかの調査の結果、これらの 4 つの方法が唯一のものであるように思われるため、今何をすべきかまったくわかりません。
事前にご協力いただきありがとうございます。
2 つの jnlp ファイルと、アプレットを起動する html ファイルを追加します。
HTML:
<html>
<head>
<title>Some title</title>
</head>
<body>
<center>
<applet code="guiconcepts/AppletTest.class"
width=1600
height=1010
archive="SConfigTest.jar">
<param name="codebase_lookup" value="false">
<param name="subapplet.classname" value="SConfigTest">
<param name="subapplet.displayname" value="SConfigTest">
<param name="noddraw.check" value="true">
<param name="progressbar" value="true">
<param name="jnlpNumExtensions" value="1">
<param name="jnlpExtension1"
value="http://download.java.net/media/jogl/jsr-231-2.x-
webstart/jogl-core.jnlp">
<param name="java_arguments" value="-Dsun.java2d.noddraw=true">
<param name="jnlp_href" value="AppletTest.jnlp">
</applet>
</center>
</body>
</html>
AppletTest.jnlp:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.5+" codebase="./"
href="AppletTest.jnlp">
<information>
<title>Some title</title>
<vendor>Some vendor</vendor>
<homepage href="http://www.somePage.com"/>
<description>Java Applet Test</description>
<description kind="short">Test of a Java Applet</description>
<offline-allowed/>
</information>
<update check="background" policy="always"/>
<resources>
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
<property name="sun.java2d.noddraw" value="true"/>
<extension name="JOGL" href="JOGL.jnlp" />
<jar href="jai_core.jar" />
<jar href="jai_codec.jar" />
<jar href="mlibwrapper_jai.jar" />
<jar href="SConfigTest.jar" main="true"/>
</resources>
<applet-desc
name="AppletTest"
main-class="guiconcepts.AppletTest"
width="1600"
height="1010">
</applet-desc>
</jnlp>
JOGL.jnlp:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="./"
href="JOGL.jnlp">
<information>
<title>JOGL libraries</title>
<vendor>JogAmp Community</vendor>
<homepage href="http://jogamp.org/"/>
<description>JOGL libraries</description>
<description kind="short">
All JARs and native libraries for JOGL.</description>
<offline-allowed/>
</information>
<update check="background" policy="always"/>
<security>
<all-permissions/>
</security>
<resources>
<jar href="gluegen-rt.jar" />
<jar href="jogl.all.jar" />
</resources>
<resources os="Windows" arch="x86">
<nativelib href = "gluegen-rt-natives-windows-i586.jar" />
<nativelib href = "jogl-all-natives-windows-i586.jar" />
</resources>
<resources os="Windows" arch="amd64">
<nativelib href = "gluegen-rt-natives-windows-amd64.jar" />
<nativelib href = "jogl-all-natives-windows-amd64.jar" />
</resources>
<resources os="Windows" arch="x86_64">
<nativelib href = "gluegen-rt-natives-windows-amd64.jar" />
<nativelib href = "jogl-all-natives-windows-amd64.jar" />
</resources>
<resources os="Linux" arch="i386">
<nativelib href = "gluegen-rt-natives-linux-i586.jar" />
<nativelib href = "jogl-all-natives-linux-i586.jar" />
</resources>
<resources os="Linux" arch="x86">
<nativelib href = "gluegen-rt-natives-linux-i586.jar" />
<nativelib href = "jogl-all-natives-linux-i586.jar" />
</resources>
<resources os="Linux" arch="amd64">
<nativelib href = "gluegen-rt-natives-linux-amd64.jar" />
<nativelib href = "jogl-all-natives-linux-amd64.jar" />
</resources>
<resources os="Linux" arch="x86_64">
<nativelib href = "gluegen-rt-natives-linux-amd64.jar" />
<nativelib href = "jogl-all-natives-linux-amd64.jar" />
</resources>
<resources os="Mac OS X" arch="i386">
<nativelib href = "gluegen-rt-natives-macosx-universal.jar" />
<nativelib href = "jogl-all-natives-macosx-universal.jar" />
</resources>
<resources os="Mac OS X" arch="x86_64">
<nativelib href = "gluegen-rt-natives-macosx-universal.jar" />
<nativelib href = "jogl-all-natives-macosx-universal.jar" />
</resources>
<component-desc />
</jnlp>
[編集:] 問題の原因を突き止めたようです (ただし、まだ解決策はありません)。特定のブラウザの 32 ビット バージョンでアプレットを起動すると、ブラウザは jnlp ファイル内の jvm 設定に対応できない 32 ビット jre を起動します。
32 ビット マシンで 32 ビット jvm を呼び出すと問題なく動作するため、これは非常に奇妙です。
64 ビット ブラウザ (IE 64 ビット バージョンや Nightly Firefox 64 ビルドなど) でアプレットを起動すると、「正しい」jvm が呼び出され、正常に実行されます。
したがって、本当の問題は、32ビットブラウザから64ビットjvmを起動する方法だと思います(これは可能ですか?)。
ただし、エラーを再現するための小さなテスト プログラムを作成しました。このプログラムは、大きな画像を配列に格納します。32 ビット ブラウザでは、OutOfMemoryException が発生するまで、2 ~ 3 個の画像をロードできるはずです。プログラムをテストしたい場合は、jar を作成して署名し、SConfigTest.jar という名前を付ける必要があります。
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
public class AppletTest extends JApplet {
private static final long serialVersionUID = 1L;
public AppletTest() {
}
public void init() {
/*
* settings if using a proxy server
*/
/*
Properties p = System.getProperties();
p.put("http.proxyHost", "proxy.address.com");
p.put("http.proxyPort", "8080");
System.setProperties(p);
//*/
System.out.println("Applet initialized");
}
public void start() {
System.out.println("Applet starting");
BufferedImage[] imgArray = new BufferedImage[20];
/*
* load 20 copies of the image into the memory
*/
for(int i = 0; i < imgArray.length; i++) {
try {
URL imageUrl = new URL("http://www.raize.ch/Reisen/" +
"velo-eurasien/karten-rollover/" +
"western-tibet-highway_" +
"satellitenbild_grossplus.jpg");
InputStream in = imageUrl.openStream();
imgArray[i] = ImageIO.read(in);
in.close();
System.out.println("Image no. " + (i + 1) + " loaded!");
}
catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("All images loaded");
/*
* display the image inside the browser window
*/
this.setSize(imgArray[0].getWidth(), imgArray[0].getHeight());
this.getContentPane().add(new JLabel(new ImageIcon(imgArray[0])));
}
public void stop() {
System.out.println("Applet stopping");
}
public void destroy() {
System.out.println("Applet destroyed");
}
}