2

我将我的一个程序从一个独立的 Java 应用程序移植到一个 Java 小程序。该应用程序处理大型图像文件,因此我需要更多堆空间,因此将它们加载到内存中。然后将图像用作我使用 JOGL 的 openGL 窗口中的纹理数据

该应用程序在 Eclipse 中运行良好(作为小程序以及独立),如果我将独立应用程序导出为可执行 jar。我在各种系统上进行了测试(带有 4 gig ram 的 Windows XP 32、带有 12 gig ram 的 Windows XP 64 和带有 4 和 8 gig ram 的 Windows 7 64 位)。

当我导出程序的小程序版本时出现问题。在我签署了 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 文件和启动 applet 的 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 位版本启动小程序,浏览器将启动 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");
    }
}
4

1 回答 1

1

坚持initial-heap-size="256M" max-heap-size="1600M"如果只是因为拼写错误会更容易出现。

不知何故,经过几次尝试,我通过四种不同的解决方案盘旋并清除了它工作的小程序缓存(但仅在 32 位 WinXP 机器上)。

这里重要的不是小程序缓存,而是缓存的 JNLP 文件。转到 Java 控制面板,找到该应用程序。并在运行之间卸载它。

于 2012-08-11T03:42:54.790 回答