views:

2443

answers:

11
+8  A: 

If you want to really look at what is going on in the VM memory you should use a good tool like VisualVM. This software is free and a great way to see what is going on.

Nothing is really "wrong" with explicit gc() calls. However, remember that when you call gc() you are "suggesting" that the garbage collector run. There is no guarantee that it will run at the exact time you run that command.

amischiefr
Just been looking at VisualVM - it's sweet.
Nick Holt
System.gc() can harm performance because it does interfere with the GC's algorithms. This can degrade all the subsequent GCs.
Mr. Shiny and New
[citation needed] Care to demonstrate your claim? Please explain how making a call to gc() "interfere's" with the garbage collectors algorithms and how a call to a method 'degrades' subsequent calls?
amischiefr
I have used visual VM and it works awesome. It shows so much inside details inside server .
vsingh
There's a reason why the VM has a -XX:+DisableExplicitGC option! The problem isn't that it is necessarily bad to call GC. But it can be bad if you call GC *too often*. It can cause a full GC, when most of the algorithms don't stop the whole VM to do a full GC. This can be expecially problematic if you're running a HUGE, where the whole VM could pause for minutes. If that happens, you could caues other operations to time out (like database connections, rmi connections, etc)
John Gardner
See also: http://developers.sun.com/events/techdays/presentations/locations-2007/shanghai/java_track2/td_sha_perf_tuning_lee.pdf
John Gardner
+1  A: 

I would say that the consultant is right in the theory, and you are right in practice. As the saying goes:

In theory, theory and practice are the same. In practice, they are not.

The Java spec says that System.gc suggests to call garbage collection. In practice, it just spawns a thread and runs right away on the Sun JVM.

Although in theory you could be messing up some finely tuned JVM implementation of garbage collection, unless you are writing generic code intended to be deployed on any JVM out there, don't worry about it. If it works for you, do it.

Yishai
+5  A: 
Tom
+4  A: 

Take a look at the JVM args: http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#DebuggingOptions

XX:-PrintGC Print messages at garbage collection. Manageable.

-XX:-PrintGCDetails Print more details at garbage collection. Manageable. (Introduced in 1.4.0.)

-XX:-PrintGCTimeStamps Print timestamps at garbage collection. Manageable (Introduced in 1.4.0.)

-XX:-PrintTenuringDistribution Print tenuring age information.

While you're not going to upset the JVM with explicit calls to System.gc() they may not have the effect you are expecting. To really understand what's going on with the memory in a JVM with read anything and everything the Brian Goetz writes.

Nick Holt
+1  A: 

If you use java 1.5, you can look at ManagementFactory.getMemoryMXBean() which give you numbers on all kinds of memory. heap and non-heap, perm-gen.

A good example can be found there http://www.freshblurbs.com/explaining-java-lang-outofmemoryerror-permgen-space

Zoukaye
+3  A: 

There are tools that let you monitor the VM's memory usage. The VM can expose memory statistics using JMX. You can also print GC statistics to see how the memory is performing over time.

Invoking System.gc() can harm the GC's performance because objects will be prematurely moved from the new to old generations, and weak references will be cleared prematurely. This can result in decreased memory efficiency, longer GC times, and decreased cache hits (for caches that use weak refs). I agree with your consultant: System.gc() is bad. I'd go as far as to disable it using the command line switch.

Mr. Shiny and New
+1 for the excellent comment on premature promotion.
Robert Munteanu
+2  A: 

Explicitly running System.gc() on a production system is a terrible idea. If the memory gets to any size at all, the entire system can freeze while a full GC is running. On a multi-gigabyte-sized server, this can easily be very noticeable, depending on how the jvm is configured, and how much headroom it has, etc etc - I've seen pauses of more than 30 seconds.

Another issue is that by explicitly calling GC you're not actually monitoring how the JVM is running the GC, you're actually altering it - depending on how you've configured the JVM, it's going to garbage collect when appropriate, and usually incrementally (It doesn't just run a full GC when it runs out of memory). What you'll be printing out will be nothing like what the JVM will do on it's own - for one thing you'll probably see fewer automatic / incremental GC's as you'll be clearing the memory manually.

As Nick Holt's post points out, options to print GC activity already exist as JVM flags.

You could have a thread that just prints out free and available at reasonable intervals, this will show you actual mem useage.

Steve B.
How is this mitigated by not calling System.gc()? Eventually the JVM garbage collects when it runs low on memory, so won't the delay happen then? (That has been my experience at least).
Yishai
The JVM allows you to specify from multiple GC algorithms. They all do some sort of incremental GC, and may occasionally trigger a full GC (I'm not too up on the details, but basically only when they have to - sort of a "last resort" kind of thing, e.g. when there's not enough room to make a new copy of some section of mem during incremental gc). If you're regularly calling System.gc it's going to happen much more often. You're essentially creating your own GC strategy, which is "just periodically run a full GC". The JVM has better strategies than this.
Steve B.
A: 

As has been suggested, try VisualVM to get a basic view.

You can also use Eclipse MAT, to do a more detailed memory analysis.

It's ok to do a System.gc() as long as you dont depend on it, for the correctness of your program.

Aakash
+1  A: 

If you like a nice way to do this from the command line use jstat:

http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html

It gives raw information at configurable intervals which is very useful for logging and graphing purposes.

Pablojim
A: 

The problem with system.gc, is that the JVM already automatically allocates time to the garbage collector based on memory usage.

However, if you are, for instance, working in a very memory limited condition, like a mobile device, System.gc allows you to manually allocate more time towards this garbage collection, but at the cost of cpu time (but, as you said, you aren't that concerned about performance issues of gc).

Best practice would probably be to only use it where you might be doing large amounts of deallocation (like flushing a large array).

All considered, since you are simply concerned about memory usage, feel free to call gc, or, better yet, see if it makes much of a memory difference in your case, and then decide.

PiPeep
+1  A: 

Peek into what is happening inside tomcat through Visual VM. http://www.skill-guru.com/blog/2010/10/05/increasing-permgen-size-in-your-server/ alt text

alt text

vsingh
why is image not showing up ?
vsingh