ZACZEK, MARIUSZ P. (MARIO) (JSC-DM) (NASA) wrote:
Below is a copy of a post someone put to this group in 1998!!! There was no
answer
in that thread and searching the archives I have not yet found an
answer...so, I'm
going to ask you all about it. Do you know how to get back the memory after
removing
a child from a parent?

Hi, I did some test and I found almost the same thing.

I start the program where just one shape is added.
Mem is 1100
Then i add 500 new shapes, call gc, and the memory goes to 2200.
Now I remove all the shapes, call gc, and memory goes up to 2700 (???)
I add and remove shapes, call gc, and memory goes up and down, from 2700
to 4000.

If I add more shapes (es. 10000) the result is similar but more memory
is "lost" when all the shapes are removed.

The only thing i noticed is that the arraylist that contains the
children of shapeRoot (see code) is not trimmedToSize after childern are
removed, so it remains to full size. I do not think this can explain the
full thing cause i think the array internal to arrayList hold just the
space for the references and not for full objects (even it would be nice
to have even those few bytes back).

Then i tryed not to call gc and the results are incredible :)
Memory goes down even to 330.
Sometimes adding or removing cause memory to go up to 2200, other times
it falls back to 400. On average it stays around 800/1400.

So...do not call gc :)


PS I know that scenegraph should be modifyed only from the processstimulus of a behavior but I hope this is not relevant in this case.


Bye
package mesh;

import java.applet.Applet;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.geometry.NormalGenerator;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;


public class HelloUniverse extends Applet {

        private SimpleUniverse u = null;
        private BranchGroup shapeRoot;
        Button b = new Button("ADD");

        final int COUNT = 500;
        boolean added = false;

        public HelloUniverse() {

        }

        private void addShapes() {

                System.out.println("Adding....");
                for (int i = 0; i < COUNT; i++) {
                        BranchGroup group = createShape();
                        shapeRoot.addChild(group);
                }
                b.setLabel("REMOVE");
                System.out.println("Added");
        }

        private void removeShapes() {
                System.out.println("Removing...");
                shapeRoot.removeAllChildren();
                b.setLabel("ADD");
                System.out.println("Removed");
        }

        private Runtime rt = Runtime.getRuntime();
        private void dumpMem() {

                System.out.println("1. " + (rt.freeMemory()/1000) + "/" + (rt.totalMemory()/1000));
                System.gc();
                System.out.println("2. " + (rt.freeMemory()/1000) + "/" + (rt.totalMemory()/1000));
        }

        public BranchGroup createSceneGraph() {

                BranchGroup objRoot = new BranchGroup();

                //here i add my test shapes
                shapeRoot = new BranchGroup();
                shapeRoot.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
                shapeRoot.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);

                //add a shape just to load all classes
                objRoot.addChild(shapeRoot);

                BranchGroup group = createShape();
                shapeRoot.addChild(group);

                objRoot.compile();

                return objRoot;
        }

        public BranchGroup createShape() {

                float[] vertex = {      0.5f, -0.5f, 0, //centro
                                                        -0.5f, 0.5f, 0,
                                                        -0.5f, -0.5f, 0,
                                                        0.5f, 0.5f, -0.4f, //secondo fan
                                                        -0.5f, 0.5f, 0 };

                GeometryInfo geomInfo = new GeometryInfo(GeometryInfo.TRIANGLE_FAN_ARRAY);
                geomInfo.setCoordinates(vertex);
                geomInfo.setStripCounts(new int[]{5});

                NormalGenerator ng = new NormalGenerator();
                ng.generateNormals(geomInfo);

                GeometryArray tFan = geomInfo.getGeometryArray();

                Shape3D shape = new Shape3D(tFan);
                BranchGroup group = new BranchGroup();
                group.setCapability(BranchGroup.ALLOW_DETACH);
                group.addChild(shape);
                return group;
        }

        public void destroy() {
                u.removeAllLocales();
        }

        public void init() {

                setLayout(new BorderLayout());

                GraphicsConfiguration config =
                        SimpleUniverse.getPreferredConfiguration();
                Canvas3D c = new Canvas3D(config);
                add(BorderLayout.CENTER, c);

                add(BorderLayout.SOUTH, b);
                b.addActionListener(new ActionListener(){
                        public void actionPerformed(ActionEvent e) {
                                if (added)
                                        removeShapes();
                                else
                                        addShapes();
                                added = !added;
                                //remove comment to call gc
                                //dumpMem();
                        }
                });

                Button gc = new Button("GC");
                add(BorderLayout.NORTH, gc);
                gc.addActionListener(new ActionListener(){
                        public void actionPerformed(ActionEvent e) {
                                dumpMem();
                        }
                });

                Button mem = new Button("MEM");
                add(BorderLayout.EAST, mem);
                mem.addActionListener(new ActionListener(){
                        public void actionPerformed(ActionEvent e) {
                                System.out.println("mem " + (rt.freeMemory()/1000) + "/" + (rt.totalMemory()/1000));
                        }
                });


                BranchGroup scene = createSceneGraph();
                u = new SimpleUniverse(c);
                u.getViewingPlatform().setNominalViewingTransform();
                u.addBranchGraph(scene);
        }

        public static void main(String[] args) {
                new MainFrame(new HelloUniverse(), 512, 512);
        }
}

Reply via email to