1

First of all, I can't really show code, I am sorry, these software belongs to the company I work for, not me. I will try to explain my problem the best I can.

I am developing a little application based on JavaFX, that shows values in LineCharts, these are refreshed every 800ms-1000ms (0,8-1 seconds), and calls System.gc() every time I refresh (Around once every 0,8-1 seconds).

I am having RAM usage peaks every 10-20 seconds:

enter image description here In this specific example, this doesn't look like a problem, but in some cases it goes up to 700-750 MB (Making the Heap Size go up to 1.2-1.3 GB, and taking a long time to release it back to the OS).

I know about (and currently use, without noticing any huge improvement) Heap Tuning Paremeters, but I don't think these can fix the problem here, they are helping at specific points, and slightly reduce the memory consumption, but not solve the problem.

Any ideas on how can I design my code not to have these RAM peaks? I don't have a process that uses memory and releases it every 10-20 seconds, so I assume there is something else allocating and releasing that ammount of RAM (Maybe JavaFX?), JVisualVM only says int[], byte[] and char[], and I am not even using Integer values in my code (I work with Double values in this software).

Thank you all.

Mayuso
  • 1,203
  • 3
  • 17
  • 39

3 Answers3

2

Sorry, but the only reasonable answer here: you have to do profiling in order to understand where those peaks are coming from. You have to identify the root cause of this problem; and that is nothing that we can help with.

This program runs in your setup, with your data, and shows behavior that needs to analyzed over time.

My guess would be that your program is creating large amounts of objects that will be thrown away quickly afterwards ( I guess you have those calls to System.gc() in there for a reason). And guess what: creating garbage on high rate is a bad idea. Because it keeps your GC constantly spinning; and it (obviously?!) contributes to high memory load.

So, as said: you have to identify the root cause and fix that. In that sense: you have to study the tooling you are using. An alternative to profiling might be to have the GC log its activities; and analyze that output. See here for some information on that.

GhostCat
  • 127,190
  • 21
  • 146
  • 218
  • I am profiling with JVisualVM, but it doesn't give me any meaningful information (Probably because I don't really know how to use it?). All I can see is (as I said), byte[], int[], and char[] use a lot of RAM (Around 20-30MB each), but that's all that this software shows me. – Mayuso Sep 12 '16 at 09:10
  • Probably; but we also cant help with that easily; but I put some updates into my answer. – GhostCat Sep 12 '16 at 09:13
  • I answered my own question with the solution, this really helped me. Thank you. – Mayuso Sep 12 '16 at 09:23
  • @Mayuso I would use JMC, but those arrays don't exist in isolation or spontaneously, there are operations being performed which create them. – Peter Lawrey Sep 12 '16 at 10:20
2

I found the solution:

Both MrSmith42 and GhostCat pointed out that calling System.gc() doesn't really help me here. They were right, in fact, that was the problem.

Removing System.gc() solved the problem for me

enter image description here Thank you, MrSmith42 and GhostCat.

Mayuso
  • 1,203
  • 3
  • 17
  • 39
  • Interesting. I leave the question how to accept all three given answers to you ;-) ... and for the record: you might still want to look into the details here; just to understand what is going on; and to be prepared for the next event of that kind. – GhostCat Sep 12 '16 at 09:25
  • @Mayuso: There seams to be still a slow constant increase in memory usage. You should check if this behavior continues over time. – MrSmith42 Sep 12 '16 at 09:55
  • Thank you both for the feedback, yes, I definitely need to keep working on memory usage and my understanding of the JVM in general. Regarding the increasing RAM usage, it actually makes sense as each second I am adding hundreds of values to the charts (256 different variables get new values every 0,8-1 second), but it is probably still increasing too fast, I might have a leak somewhere. – Mayuso Sep 12 '16 at 10:01
  • And GhostCat, I still don't know what answer to mark as the Valid/Correct one, as both helped me xD I don't know what people in stackoverflow do in these cases. – Mayuso Sep 12 '16 at 10:04
1

System.gc() does not trigger a garbage collection directly it is more like a hint to the VM that you think performing a garbage collection would be a good idea. What your VM does is its own decision based on the implementation. Only if the VM runs out of memory it will sure perform a garbage collection but that also without you calling System.gc(). A quite long discussion about this topic can be found here:

When does System.gc() do anything

Community
  • 1
  • 1
MrSmith42
  • 9,218
  • 6
  • 35
  • 48