我将我的一个程序从独立的 Java 应用程序移植到 Java applet。该应用程序处理大型图像文件,因此我需要更多堆空间,因此将它们加载到内存中。这些图像然后在我使用 JOGL 的 openGL 窗口中用作纹理数据
如果我将独立应用程序导出为可执行 jar,则该应用程序在 eclipse 中(作为小程序以及独立应用程序)运行良好。我在各种系统上对此进行了测试(Windows XP 32 和 4 gig ram,Windows XP 64 和 12 gig ram 以及 Windows 7 64 位和 4 和 8 gig ram)。
当我导出小程序版本的程序时出现问题。在我签署 jar 并尝试在浏览器(测试过 Firefox 和 IE)中运行它之后,应用程序总是在上述 64 位机器上崩溃并出现 OutOfMemory 异常。
但是在 Windows XP 32 位机器上,它在一些摆弄之后工作了,但我不知道为什么,因为我所做的只是尝试不同的解决方案,并且其中一个以某种方式工作,即使这种方式也会导致崩溃以前的尝试。
我尝试了四种方法来增加堆空间
在我试过的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"/>
在资源标签内,在尝试了几次之后,我以某种方式在四种不同的解决方案中循环并清除了它有效的小程序缓存(但仅在 32 位 WinXP 机器上)。
但我没有成功尝试在 64 位机器上运行小程序,我完全不知道现在该做什么,因为经过一些研究后,这四种方法似乎是唯一的。
提前感谢您的帮助。
我将添加两个 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>
小程序测试.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>
[edit:] 看来我找到了导致问题的原因(但仍然没有解决方案)。如果我使用任何给定浏览器的 32 位版本启动小程序,浏览器将启动 32 位 jre,它无法处理 jnlp 文件中的 jvm 设置。
这真的很奇怪,因为在 32 位机器上调用 32 位 jvm 工作得很好。
如果我使用 64 位浏览器(如 IE 64 位版本或 Nightly Firefox 64 版本)启动小程序,则会调用“正确”的 jvm 并且运行正常。
所以我想真正的问题是如何从 32 位浏览器启动 64 位 jvm(这甚至可能吗?)。
但是我写了一个小测试程序来重现错误。该程序将大图像存储在数组中。使用 32 位浏览器,您应该能够加载 2-3 个图像,直到出现 OutOfMemoryException。如果您想测试该程序,您必须创建一个 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");
}
}
最佳答案
坚持使用 initial-heap-size="256M"max-heap-size="1600M"
只是因为拼写错误更容易出现。
somehow after a few tries were I circled through the four different solutions and clearing the applet cache it worked (but only on the 32 bit WinXP machine).
这里重要的不是applet缓存,而是缓存的JNLP文件。转到 Java 控制面板,找到该应用程序。并在运行之间卸载它。
关于java - 增加 Java 小程序的堆大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11905301/