Increase the heap size of a Java applet

5k Views Asked by At

I ported one of my programs from a standalone Java application to a Java applet. The application processes large image files so I need more heap space so load them into the memory. The images are then used as texture data in an openGL window for which I used JOGL

The application works fine inside of eclipse (as applet aswell as standalone) and if I export the standalone application as an executable jar. I tested this on various systems (Windows XP 32 with 4 gig ram, Windows XP 64 with 12 gig ram and Windows 7 64 bit with 4 and with 8 gig ram).

The problem occures when I export the applet version of the program. After I signed the jar and try to run it in a browser (tested Firefox and IE) the application always crashes with an OutOfMemory exception on the 64 bit machines described above.

On the Windows XP 32bit machine however it worked after a bit of fiddling but I don't know why because all I did was to try different solutions and somehow one of them worked even if this way also lead to a crash in a previous attempt.

There are four ways I tried to increas the heap space

In the html file I tried:

<PARAM name="java_arguments" value="-Xmx1600m">

which didn't work.

Then I tried to increase the heap directly via the Java menu (Start -> Control Panel -> Java tab -> Java Runtime Environment Settings) with the -Xmx1600M argument. This hat also no impact.

After that I used a jnlp file from the guys at Jogamp. There I added

<j2se version="1.6+" java-vm-args="-Xmx1600m" 
    href="http://java.sun.com/products/autodl/j2se"/>

inside the resource tag. This had initially also no effect.

Lastly I added

<j2se version="1.6+" initial-heap-size="256M" max-heap-size="1600M" 
    href="http://java.sun.com/products/autodl/j2se"/>

inside the resource tag and 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).

But I hat no success trying to run the applet on the 64 bit machines and I have absolutly no clue what to do now because after some research those four methos seem to be the only one.

Thanks for your help in advance.

I will add the two jnlp files and the html files that starts the applet.

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>

[edit:] It seems that I found what's causing the problem (but stil no solution). If I start the applet with a 32-bit version of any given browser the browser starts the 32-bit jre which cannot cope with the jvm-settings inside the jnlp-files.

Thats is really odd because calling the 32-bit jvm on a 32-bit machine works just fine.

If I start the applet with a 64-bit browser (like the IE 64-bit version or the Nightly Firefox 64 build) the "correct" jvm is called and it runs a okay.

So I guess the real question is how to start the 64-bit jvm from a 32-bit browser (is this even possible?).

However I wrote a small test program to reproduce the error. The program stores a large image in an array. With the an 32-bit browser you should be able to load 2-3 images until you get an OutOfMemoryException. If you want to test the program you have to create a jar and sign it afterwards and name it 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");
    }
}
1

There are 1 best solutions below

2
On

Stick with initial-heap-size="256M" max-heap-size="1600M" if only for the fact that spelling mistakes will show up more easily.

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).

It is not the applet cache that is important here, but the cached JNLP file. Go to the Java Control Panel, find the app. and uninstall it between runs.