1

Application Description: I have an application in JAVA which is used to generate charts. The user can set up the charts with the help of a GUI according to his needs.

Problem Description: When a chart is created certain amount of memory is used and when a new chart is created the memory used by the previous chart is not cleared by the GC automatically however, if I insert a System.gc() statement the memory is cleared. I want the memory to clear all the dead objects each time a new chart is generated.

Question Why doesn't the GC work automatically as it should do in Java ? Thanks for your inputs.

maaartinus
  • 44,714
  • 32
  • 161
  • 320
Adi
  • 57
  • 1
  • 9
  • http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html – kosa Oct 29 '13 at 17:41
  • 3
    a) How do you know the memory isn't freed? b) Is this actually a problem for you? The GC only runs when the memory is actually needed. – Louis Wasserman Oct 29 '13 at 17:41
  • Read a little about garbage collection in Java. GC does not run automatically (and doesn't need to). http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html – Marcelo Oct 29 '13 at 17:42
  • 1
    The GC does work automatically as it should, it just doesn't do it the way you think it should. Performing the GC is expensive so it only does it when it needs to not every time you discard something as this would be much, much slower, if not make the program unusable. a minor GC typically takes 1 ms, so if you performed one thousand per second, discarding one thousand object your program wouldn't do anything else. However, if you only clean up objects when you need to, it can run for seconds, minutes or even hours without a GC saving a lot of time. – Peter Lawrey Oct 29 '13 at 19:57
  • Hi Louis I profiled the application and saw that whenever you create a new chart the memory from the previous chart remains and the application builds from that point in the memory, instead of clearing the memory and then making the new chart. System.gc() triggers the GC and is clearing the memory. This is a problem because when the used memory approaches the limit of 1 GB the programs starts slowing down. – Adi Oct 30 '13 at 20:44
  • Thanks for the link Marcelo – Adi Oct 30 '13 at 20:45
  • Hi Peter , I agree that the GC should work automatically and adding System.gc() has the potential of hampering the program. However, the application doesn't seem to be clearing the memory at all but just grow whenever a new chart is being created (causing the app to become slower progressively) and adding System.gc() somehow solves this issue. I am trying to figure out how the GC is running with respect to my application and why it doesn't get triggered automatically. – Adi Oct 30 '13 at 20:56

2 Answers2

2

Don't use System.gc. There is no guarantee that memory will get cleared and it is a sign that there are other problems with your code. The GC will work as it should and is usually not to blame for the problems.

How do you know the GC is at fault? Some options to consider:

  • Have you profiled your code to see how it is using memory and if memory is being freed?
  • Are you holding onto objects longer than you should?
  • If all is well, have you tried increasing the heap size using Xmx and Xms?
  • Another option is to consider tuning the GC to make it behave how you want.

The thing about GC'ed systems is that you shouldn't have to worry about memory management (in most cases) and you can trust that the GC will take care of it for you. All you need to care about is whether you're blowing the top off your heap and from what you have described, it doesn't seem like you're running out of memory. You can rest assured that the GC will collect unused memory at a time that it sees fit. To control the behavior, you will have to tune the GC.

Community
  • 1
  • 1
Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • 2
    He claimed that `System.gc` helped, so there is no memory leak. I think he just wants it to be cleared at certain point in time (when new chart is created) and this is simply not (and can't be) guaranteed . – Jan Zyka Oct 29 '13 at 17:43
  • @JanZyka Oops I didn't see that part, but using `System.gc` is a sign that there is a larger problem and even if it *is* clearing memory, you cannot rely on it to do so since the JVM can be started with flags that prevents `System.gc` from working. – Vivin Paliath Oct 29 '13 at 17:44
  • I think there is not necessary a problem. He didn't say he ever saw `OutOfMemory` error. My feeling is there is no problem at all. He just didn't understand how exactly garbage collection works. – Jan Zyka Oct 29 '13 at 17:45
  • @JanZyka Weird I could have sworn I saw him mention an `OutOfMemory` error somewhere. What you said makes sense; perhaps he is simply confused about the workings of the GC. – Vivin Paliath Oct 29 '13 at 17:47
  • I'm not sure if System.gc() is such a bad thing to call. What if you just released a whole bunch of objects, the memory from which you'll need soon. But before you need it, you have to wait for the results from a sql query to come back. You can call System.gc() then to give it a head start before you start filling all of this memory again. – Cruncher Oct 29 '13 at 17:49
  • At first I got confused by the `out-of-memory` tag as well :) – Jan Zyka Oct 29 '13 at 17:49
  • @Cruncher There are *far* greater problems with relying on `System.gc` . It is better to profile your code and learn its memory footprint and behavior and then rewrite/refactor or tune the GC. `System.gc` can even be disabled by a commandline flag to the JVM and so it is not wise to depend on it. The thing is also that you don't know for sure *what* it will do, or even *if* it will help since the GC may not even run at all (the JVM can choose to ignore it). – Vivin Paliath Oct 29 '13 at 17:53
  • @VivinPaliath I'm aware that it may not do anything. But if you know that your program is doing nothing and has to wait for IO I don't see the downside. I'm not sure what profiling has to do with it either. If you know when this IO comes in, that you're going to be filling lots of memory, why not at least give the opportunity for a well-implemented JVM to optimise the situation? If it does something harmful, then it's time for a new JVM! – Cruncher Oct 29 '13 at 17:56
  • @Cruncher The point is you *don't* need it. Also, what if the customer's JVM is configured to ignore `System.gc`. Profiling has *everything* t do with performance. Profiling is how you will understand how your program behaves and what it does with its memory. The JVM already handles memory in an optimal way based on its configuration settings. The way to make it better is to *tune* it based on your personal scenario and **not** to call `System.gc`. There are better ways; `System.gc` is not one of them. – Vivin Paliath Oct 29 '13 at 17:59
  • @VivinPaliath I think it's a little bit narrow to dismiss it as entirely useless. It wouldn't be in the language if it was such a plague. It's even good if you know your window is getting minimized to `system.gc()` then. No use in paging dead memory. – Cruncher Oct 29 '13 at 18:03
  • @Cruncher I didn't say that it's *entirely* useless, but it is useless in the *vast majority* of cases. If you're relying on `System.gc` for performance, you must have a seriously-unique circumstance. – Vivin Paliath Oct 29 '13 at 18:08
2

In java there is no guarantee for when the Garbage Collector will be run. The idea is that you should not have to worry about memory. By the time you need memory the garbage collector should have cleaned up enough space by now.

If it can't clear enough space when you need it then you'll get an OutOfMemoryError.

System.gc() is a hint to help notify the garbage collector when a good time to garbage collect might be. It does not necessarily start the garbage collector though.

Cruncher
  • 7,641
  • 1
  • 31
  • 65