Name: gm110360 Date: 06/10/2002
FULL PRODUCT VERSION :
No Command Line (using Browser to access Java Applet)
Install Java 1.4.0 Plugin on Windows 2000
Using a browser to access a webpage with an Applet.
The applet has Runtime.getRuntime().maxMemory() calls and outputs values to the
standard out (console).
FULL OPERATING SYSTEM VERSION : MS Windows 2000
ADDITIONAL OPERATING SYSTEMS : RedHat Linux 7.1
EXTRA RELEVANT SYSTEM CONFIGURATION :
512MB RAM
1.2GHz Pentium III
A DESCRIPTION OF THE PROBLEM :
Console output from a Java Applet with calls to
Runtime.getRuntime().maxMemory() return incorrect values.
Using Sun JRE 1.4.0 and configuring the ControlPanel->Java
Plugin 1.4.0 VM Parameters with different parameters,
yields incorrect results.
-Xms -Xmx
VM Parameter maxMemory() totalMemory() freeMemory()
------------- ----------- ------------- ------------
(none) 163 Meg 17 Meg 7 Meg
128m 256m 327 Meg 130 Meg 113 Meg
With no parameters, the maximum heap size is 64 Meg. This
is true, and my applet throws an OutOfMemory exception at
64 Meg, however the maxMemory always reports 163 Meg.
With -Xms128m -Xmx256m, the maximum heap size is 256 Meg.
This is true, and my applet throws an OutOfMemory exception
at 256 Meg, however the maxMemory always reports 327 Meg.
This is a real problem, since I know of no other way to
query memory bounds. We must have a method to determine how
much memory we can use because out of memory exception
handling is not acceptable way to hanlde program control.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Install Sun Java Plugin 1.4.0
2. Do not set VM parameters
3. Call applet that displays Runtime.getRuntime().maxMemory
() and see that value is 163 Meg (approx 163*1024000
bytes). Which is wrong. The maxMemory() with no options, is
64 Meg.
4. Try different -Xms -Xmx values and do step 3 and record
results. (ie. -Xms128m -Xmx256m)
EXPECTED VERSUS ACTUAL BEHAVIOR :
Runtime.getRuntime().maxMemory() should return the upper
bounds of the memory available to this runtime.
Even though the you are not gauranteed the amount of memory
you request in -Xmx<ZZZ>m, you still trust the user has set
this amount for a reason. In addition, the value can be
larger than physical memory (ie. -Xmx1000m) and should
work, assuming there is physical disk space to accomdate
the paging needs for the additional memory needed beyond
physical memory (ie. you have 256M RAM, you set -Xmx1000m,
paging to disk begins after the 256M RAM is exausted).
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Use simple print statements in your applet to display runtime memory:
public void printRT() {
System.out.println("Max: " + Runtime.getRuntime().maxMemory() );
System.out.println("Total: " + Runtime.getRuntime().totalMemory() );
System.out.println("Free: " + Runtime.getRuntime().freeMemory() );
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Use try/catch statements on memory intensive areas to catch
OutOfMemoryError exceptions. In addition, it takes memory
to handle exceptions. In the exception handling, you must
purge some or all items using the memory. Then what? Find
some other creative way to try again (what originally
failed) using less memory, not an easy task. No way to do
this everywhere as everything uses memory, plus it's very
ugly and difficult to maintain. Without "knowing" the
memory bounds in an applet, you cannot look ahead to
predict if you have enough memory to do what the user
wants. For instance, you need to load 200 images into
memory and they are all 1024x1000 and you're trying to fit
them on a 1024x1000 canvas. Can your applet calculate if
there is enough room? No. You can do the math, you know you
will need at least 1Meg per image just for the pixels and
some fixed value for the objects you create for the image
objects per image. You have to start one by one, if they
all load, great. If not, you ran out of memory and you
start over loading them into a different size panel, or
something. Not very elegant.
(Review ID: 146167)
======================================================================