增加Java小程序的堆大小

问题描述:

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

该应用程序在eclipse(作为小程序和独立程序)内工作良好,并且将独立应用程序作为可执行程序jar导出。我在各种系统上测试过这个(Windows XP 32有4个ram,Windows XP 64有12个ram,Windows 7 64位有4个和有8个ram)。

当我导出程序的小程序版本时,会出现问题。在我签名jar并尝试在浏览器(经过测试的Firefox和IE)中运行它之后,应用程序总是会在上述64位机器上发生OutOfMemory异常而崩溃。

在Windows XP 32bit计算机上,它工作了一段时间后,但我不知道为什么,因为我所做的只是尝试不同的解决方案,其中一个工作,即使这种方式也导致崩溃以前的尝试。

有四种方法我试过的人口增加堆空间

在我试过的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位机器上运行applet并没有成功,我绝对不知道该怎么做,因为经过一番研究,这四种方法似乎是唯一的方法。

感谢您的帮助提前。

我将添加两个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"); 
    } 
} 
+0

顺便说一句 - 你的问题是什么? – 2012-08-11 03:43:09

+0

对不起,我尝试澄清它。我想知道为什么我的applet不会创建jvm correcly,因此运行所需的堆空间少于OutOfMemory异常。 – Scyla 2012-08-16 07:36:13

棒与initial-heap-size="256M" max-heap-size="1600M"如果只为一个事实,即拼写错误将显示更容易。

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

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

+0

Tahnks的信息。我用javaws -clearcache清除了缓存,这似乎也清除了缓存的JNLP文件。一个附加信息:在我切换到java 1.7.0_06后,我在java控制台中获得了额外的消息,主要是匹配:运行JVM参数不匹配:have:!satisfy want:我尝试写一个小程序,我可以在这里发布以复制错误。 – Scyla 2012-08-16 07:54:07

+0

我编辑了我的第一篇文章,因为我可以找出导致错误的原因。我还添加了一个小例子程序,应该能够重现错误。 – Scyla 2012-08-16 15:56:46