0

I built a JavaFX(8) 3D application, which reads data from some file and renders it on some scene.

For rendering an object, I use:

graphicsContainer.getChildren().add(some3dObject);

When I comment out this line, for disabling the rendering, I have no memory leaks at all.

But when this line does run, the application consumes more and more memory. I have 30 frames per second and every second the memory consumption raises in ~50MB.

This is of course, although between the frames I use:

graphicsContainer.getChildren().clear();

The 3D objects I assign to the graphicsContainer are local are not saved in any static/global scope. They are only saved as children of the graphicsContainer, which is cleaned on every frame.

It seems that something in the JavaFX-3D engine does not really clear my work although I remove each time the children of the graphicsContainer.

Any idea how to make JavaFX 3D engine release the past 3D objects and renderings?

SomethingSomething
  • 11,491
  • 17
  • 68
  • 126
  • What's your actual evidence that there is a memory leak? Does it eventually run out of memory completely? How do you know that the garbage collector simply hasn't determined it needs to reclaim the unused memory (yet)? – James_D Aug 31 '16 at 16:20
  • Are you running this on Linux? JavaFX has some memory leak issues on Linux with some configurations (Technically the leak is probably in Mesa, not Java, but JavaFX is the only place I've encountered it) – Itai Aug 31 '16 at 16:35
  • @James_D, I use the Windows Task Manager to see how the memory consumption of the Java process raises from 110M into 4000M gradually within 30 seconds of frames (900 frames as it's 30 fps). I tried calling the garbage collector manually after each call to `graphicsContainer.getChildren().clear()` - It only caused the CPU usage to become more than 90%, while not affecting the memory consumption – SomethingSomething Aug 31 '16 at 17:30
  • Note that as mentioned above, I currently on every frame clear the `Group` object from it children and assign new children. Maybe if I save the 3D objects from the 1st frame and each time just change their transitions according to the animation, it will work better – SomethingSomething Aug 31 '16 at 17:44
  • It seems to be much better when I save the 3D objects from the same frame and always change their attributes, instead of everytime creating new objects (although the old objects must die from my scope as I didn't save them anywhere) – SomethingSomething Aug 31 '16 at 18:02
  • So if you're up to 4GB RAM usage in 30 seconds, you could presumably let it run long enough so that it would run out of physical RAM (e.g. ~ 2 min on a 16GB machine...). One of two things would then happen: 1. memory usage will stop climbing and will start to be reclaimed, in which case there is no memory leak and you are just observing the GC making "decisions" about memory consumption versus CPU consumption, or 2. it will crash with an `OutOfMemoryError`, in which case you know there is a memory leak. This doesn't sound like a memory leak to me, but you can find out for sure. – James_D Aug 31 '16 at 18:33

1 Answers1

0

In my scenario, all the frames contain the same set of 3D objects. The only thing that changes from frame to frame is the locations and the transformations of these objects.

My workaround was to save in some array each 3D object I create (Sphere, Cylinder, etc.) - then on each frame, I just change their location and transformations, instead of creating new Group and new 3D objects each time.

The memory is now around 220MB all the time.

Kara
  • 6,115
  • 16
  • 50
  • 57
SomethingSomething
  • 11,491
  • 17
  • 68
  • 126
  • 1
    This is the way a scene graph is supposed to be used. Constantly re-creating the whole graphics stuff is not a good idea because the scene graph API is not an immediate mode rendering API. – mipa Sep 01 '16 at 08:03