Hi Ching,
A bug is filed for this problem (bug ID 4345204).
This is fixed in the next v1.2.1 beta release.
Attach is an example modify from your test program to
help clean up the memory. This will work in next
release.
(1) Before add("Center", c), we need to
remove previous canvas from container.
if (c != null) {
remove(c);
}
c = new Canvas3D(config);
add("Center", c);
(2) Clean up all Java3D related threads after each
iteraction.
u.getLocale().getVirtualUniverse().removeAllLocales();
Thanks for your bug report.
- Kelvin
--------------
Java 3D Team
Sun MicrosystemsInc.
------------- Begin Forwarded Message -------------
X-Unix-From: [EMAIL PROTECTED] Mon Jun 12 15:45:32 2000
MIME-Version: 1.0
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
Importance: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300
Date: Mon, 12 Jun 2000 15:31:16 -0700
From: Ching Lai <[EMAIL PROTECTED]>
Subject: [JAVA3D] out of memory error in java 3D
To: [EMAIL PROTECTED]
It seems Java 3D memory never get released. I modify
the HelloUniverse sample program to add a "for" loop
to create scene and SimpleUniverse. The program get
out of memory exception. I am running on NT4.0 with
256M byte of RAM on Jdk1.2.2 and J3d 1.13 release.
I did not use -Xmx options to increase heap size.
The program calls runtime.freeMemory, runtime.totalMemory and System.gc
to force garbage collection inside the "for" loop. I can see
the free memory increases after the program calls system.gc. But the
runtime.totalMemory keeps increasing until the program
runs out of memory.
I don't understand why the totalMemory keep increasing,
because the program just creates some objects and release them
inside the "for" loop so the garbage collector should free
these memory and the program can re-use the memory after that.
Does any one have the same "memory leak" problem
in using 3D? I have attached a copy of modified program
for HelloUniverse. Thanks in advance for any help.
Ching
------------- End Forwarded Message -------------
/*
* @(#)HelloUniverse.java 1.48 99/05/20 14:07:00
*
* Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.event.*;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class HelloUniverse extends Applet {
public BranchGroup createSceneGraph() {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
// Create the transform group node and initialize it to the
// identity. Enable the TRANSFORM_WRITE capability so that
// our behavior code can modify it at runtime. Add it to the
// root of the subgraph.
TransformGroup objTrans = new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRoot.addChild(objTrans);
// Create a simple shape leaf node, add it to the scene graph.
objTrans.addChild(new ColorCube(0.4));
// Create a new Behavior object that will perform the desired
// operation on the specified transform object and add it into
// the scene graph.
AxisAngle4f axisAngle = new AxisAngle4f(0.0f, 0.0f, 1.0f,
-(float)Math.PI / 2.0f);
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
4000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, objTrans, yAxis,
0.0f, (float) Math.PI*2.0f);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
rotator.setSchedulingBounds(bounds);
objTrans.addChild(rotator);
// Have Java 3D perform optimizations on this scene graph.
objRoot.compile();
return objRoot;
}
public HelloUniverse() {
Canvas3D c=null;
BranchGroup scene = null;
setLayout(new BorderLayout());
for (int i =0; i < 200; i++) {
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
if (c != null) {
remove(c);
}
c = new Canvas3D(config);
add("Center", c);
// Create a simple scene and attach it to the virtual universe
for (int k=0; k < 60; k++) {
scene = createSceneGraph();
}
SimpleUniverse u = new SimpleUniverse(c);
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
u.getViewingPlatform().setNominalViewingTransform();
forceGC(i + " ");
u.addBranchGraph(scene);
u.getLocale().getVirtualUniverse().removeAllLocales();
}
}
//
// The following allows HelloUniverse to be run as an application
// as well as an applet
//
public static void main(String[] args) {
new MainFrame(new HelloUniverse(), 256, 256);
}
public void forceGC(String name) {
Runtime r = Runtime.getRuntime();
long totalBefore = r.totalMemory()/100000;
long before = r.freeMemory()/100000;
System.gc();
long after = r.freeMemory()/100000;
long totalAfter = r.totalMemory()/100000;
System.runFinalization();
// System.out.println("dispose " + this);
System.out.println(name + " Memory : Total " + totalAfter + " (" + totalBefore
+ ")" +
" Free: " + after +
" (" + before + ")");
}
}