• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

JavaFX memory leak

 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I am trying to write an application which displays some points in a subscene.

The problem that I encountered is that the memory keeps increasing in size.

When I add points to the root of the subscene memory increases which is normal but when I call the clear() or the removeAll method it seems that the heap does not get cleaned.

I have already set the variables to null just to check if it fixes the issue but no change.

I used the Activity Monitor(aka Task Manager in Windows) to check the memory of the application.

I attached the project written in eclipse here, please have a look at the code.

https://www.dropbox.com/s/vt73ml057ym77kr/PointCloud.zip?dl=0

Thank you.
 
Tim Cooke
Sheriff
Pie
Posts: 3203
142
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Absolutely no chance am I going to click on a link to a zip file.

Please post the relevant section of code that you think is causing you problems. Don't post all the code for your entire project, just the bit you think is relevant to the problem
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator



<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.chart.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="anchorPaneOfViewPointCloud" prefHeight="595.0" prefWidth="714.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="viewPointCloud.ViewPointCloudController">
<children>
<SplitPane fx:id="splitPaneOfAnchorPaneOfViewPointCloud" prefHeight="160.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane fx:id="anchorPaneOneOfSplitPaneOfAnchorPaneOfViewPointCloud" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<SubScene fx:id="subScene" height="600.0" width="580.0" AnchorPane.bottomAnchor="-7.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
<root>
<Region />
</root>
</SubScene>
<Button fx:id="addPointsButton" layoutX="590.0" layoutY="14.0" mnemonicParsing="false" onAction="#addPointsButton" prefHeight="26.0" prefWidth="108.0" text="Add Points" />
<Button fx:id="removePointsButton" layoutX="590.0" layoutY="50.0" mnemonicParsing="false" onAction="#removePointsButton" text="Remove Points" />
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>

 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
the removePointsButton(ActionEvent event) does not clean the heap
 
Karthik Shiraly
Bartender
Posts: 1210
25
Android C++ Java Linux PHP Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Neither JVM memory management nor its impact on OS memory allocation is all that straightforward.

When references are nulled, they need not necessarily trigger a garbage collection cycle.
And when a garbage collection does happen, it need not necessarily show a reduction in the memory allocated by OS to the JVM, which is what Task manager depicts.

Think of it as a letter in an envelope. The memory allocated by OS is the envelope, while JVM heap is the letter. The letter may reduce in size without any visible change in size of envelope.

I suggest you use a tool like JVisualVM to first check if JVM heap size is reducing after Points are deleted and a garbage collection cycle runs.
If that happens there is no memory leak.
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
already did check... with visualVM...heap increases for ever with every call to the method addPointsButton() but used memory gets collected...the heap memory is the memory which shown in Task Manager or Activity Monitor(mac)...in jMonkeyEngine when I remove a Group of points the heap shows like the points were removed cause it gets lower...in JavaFX this does not happen and with every group of points added the system runs slower.What to do ?
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Even if the used memory shows like it is collected in visualVM the heap gets bigger and bigger...and it should get lower when I remove the points, right? in jMonkeyEngine it gets lower when I remove the points and I can see this in Task Manager/Activity Monitor, why doesn§t this happen here in JavaFX?!
 
Karthik Shiraly
Bartender
Posts: 1210
25
Android C++ Java Linux PHP Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'll address the issues separately to avoid confusion.

1. Is Java heap memory same as memory shown in an OS task manager?

No. That's the memory allocated by OS to JVM, not just for Java objects created by an application, but also for storing class metadata and data structures used by the JVM itself.
Heap memory is the sub portion of this memory set aside by the JVM for java object creation.
Whether JVM releases the memory when its heap reduces depends on the JVM's implementation.
For example, Sun/Oracle JVM has command line args like Xmx, Xms and HeapFreeRatio. Whether JVM releases OS allocated memory when its heap reduces depends on these settings.

2. Is there a leak in JavaFX, specifically, in Group.getChildren().clear()?

I tried your program and I see used heap reducing just fine in every case after removing points.
In some cases, I triggered a GC manually, in others it was triggered by JVM itself. See attached image.
In my opinion, there is no leak. If there was one, that used heap line is not going to drop like that.
But if you're convinced otherwise, file a bug against JavaFX with a heap dump.

3. JMonkeyEngine behaviour

From JMonkeyEngine source code, I get the impression that it does quite a bit of active memory management itself, using techniques like weak references and even triggering System.gc().
I don't know if JavaFX too does it internally, but aleast it's one possible reason why JMonkeyEngine seems more memory efficient.
Also, check what the Xmx and other such settings are for the other app which uses JMonkeyEngine.

4.
...in JavaFX this does not happen and with every group of points added the system runs slower.What to do ?


- Try setting Xms and Xmx to the same value and to a high value, so that time is not wasted on memory allocation and garbage collection.
- To see if slowness is due to garbage collection, set the command line flag to dump gc activity (I'm not sure what this is on Mac. If this is Oracle JVM or OpenJDK JVM, it's -verbose:gc.
- Too many nodes in scene graph is a well known javafx bottleneck. See if you can move away from scene graph and instead use Canvas, but this means your application will have to handle quite a bit of the rendering logic.
- There is always the possibility that javafx is simply the wrong tool for this app.
heap-analysis.png
[Thumbnail for heap-analysis.png]
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I did a screen recording in order to show what I experience.

https://www.dropbox.com/s/5wrvrasiolkq03h/MemoryIssue.mov?dl=0

1.I run the application
2.I click add points then remove points which makes the used memory to go up then down.
3.I repeat step 2 till minute 01:38 when I press 2 times on the remove points button and if I press 2 times then the used memory goes down where it almost reaches the bottom.Shouldn't it go down to the bottom when I click only once?

By clicking only 1 on remove points button the used memory stays between lets say 40mb -70mb, but by clicking twice on remove points button memory goes down to under 25 mb in visualVM.

As you can see if I toggle between add/remove the Heap increases after 2-3 add/remove operations.This never happened in jMonkeyEngine.
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How did you make the heap(the orange line) go down in the third picture with the no Xmx?

I need the heap(orange) to go down as well as the used heap(blue line)
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ok this is crazy I just notices that if I let the application running the used heap continues to increase in idle mode( when I don't use the application)

in every second it increments the used heap line(blue)

what is wrong here ?!
 
Karthik Shiraly
Bartender
Posts: 1210
25
Android C++ Java Linux PHP Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't see anything wrong with your code regarding memory, so there is nothing you can do anyway.
If you are seeing constantly increasing heap without doing anything, then take heap dump, analyze it and file a bug against JavaFX.
Since JavaFX involves OS specific graphics implementations, it's possible there is a problem in the MacOS implementation but not in other OSes.

The JMonkeyEngine comparison is also not useful, because it's an entirely different framework. If you're seeing much better performance with it, use it instead of JavaFX.

The actual problem you want solved is slow performance.
A runaway memory is one possible cause because it triggers frequent stopping of every other thread to do a full GC.
But it's also easy to test if runaway memory is the only cause by setting Xms and Xmx to very high values (say 1-1.5GB) and dumping verbose GC logs.
If those logs don't show frequent GCs but your app is still slow, then solving the memory leak is not going to solve the slow performance problem.
Use a profiler to see where the perf bottlenecks are.

 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
how did you make the heap(orange line) in the 3rd picture to go down? Did you set the JVM with -Xmx=no?

I use eclipse and I edited the eclipse.ini file with -Xmx=no and with 256mb but still no drop in heap(orange line).

Still I have to click twice on remove points for the used heap(blue line) to go down near the base line,if clicking once it drops the blue line but there is a significant space between the base line and the blue one.

Thank you very much for the response to the question of the post.
Screen Shot 2015-07-02 at 18.32.31.png
[Thumbnail for Screen Shot 2015-07-02 at 18.32.31.png]
 
Karthik Shiraly
Bartender
Posts: 1210
25
Android C++ Java Linux PHP Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No Xmx means the argument is not given at all. JVM takes the default, which is basically bounded only by RAM made available by OS.

I added points some 6 times - so 60000 points. Those are the rising steps.
I stopped after 6 times because from observation I knew adding 1 more set of points would bump up the total heap (the orange line).
The flat portion is when I did nothing for a while followed by removing all points.
The line still stays flat, because as mentioned, JVM does not do GC each time something is nulled.
The drop happened when I added a last set of points.
I'm guessing this happened because when the last set is added, JVM already knew it was short on free heap space.
When new set was created, JVM had to decide whether 1) it should expand heap by asking more memory from OS or 2) try to clear up heap and see if new allocations can be done without asking for more from OS.
So it did a GC, promptly found all the previous 60000 nulled references, cleaned them up, and allocated the last set.

 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hm,well my jvm does not lower the orange line not even if the used heap(blue) is very low.

That's why I wonder how come your jvm lowered your heap orange line in the 3rd picture?

What should I do to make mine lower the orange line?
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you very much for the reply.

I can see the drop in the heap now(orange line) after setting the heap in Run Configurations->Arguments to -Xmx=128m(just for test), 128 mb is not much but at least I can set the requested maximum memory manually.

If the heap(orange) is lower it does more GCs and at least now it does not occupy "all" the ram.

I understand better now what is happening there.

Topic solved thanks to Karthik Shiraly :* .
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic