System.gc() or Runtime.gc() if you call there is no guarantee that there will be a garbage collection. Its up to the JVM to perform a GC. Then what is the point in having such methods?
The javadoc for System.gc() and Runtime.gc() is alluding to the fact that it is possible to configure a JVM to ignore calls to those methods; e.g. using the -XX:+DisableExplicitGC JVM option.
However, they are not configured that way by default (at least in current versions of Oracle and OpenJDK Java). So, the calls will do something by default.
Having said that, in most situations it is a bad idea to call the garbage collector directly. They few cases where it is reasonable are mostly covered by the following:
if you are trying to investigate or test behavior of GC sensitive code; e.g. finalizers
if you are trying to avoid a GC pause at an inconvenient point, by running the GC at a point where the user won't notice.
I don't understand what is wrong with giving a guaranteed GC when I request System.gc()?
When you are able to invoke the garbage collector via a gc() call, it typically does a full collection. That is expensive, especially when the amount of non-garbage data is large1. Unfortunately, a lot of Java programmers don't realize this. So, (as I understand it) the primary reason for the JVM option to ignore explicit gc() calls is to mitigate the potentially catastrophic performance effect of programmers abusing the method.
If you do want your System.gc() calls to trigger a GC, the best advice is to make sure that you don't include -XX:+DisableExplicitGC in your JVM options.
Read the Oracle manual entry for the java command for more information.
1 - Most of the runtime cost of a garbage collection is in tracing and copying the graph of objects that are still reachable. If you tell the collector to run before it needs to, you reduce its efficiency. By contrast, the JVM itself knows when the heap is full, or close enough that a collection is warranted. Indeed, it can optimize for two different requirements; maximizing throughput, or minimizing GC pause times.
From the Java 7 docs
public static void gc()
Runs the garbage collector.
Calling the gc
method suggests that the Java Virtual Machine expend effort toward
recycling unused objects in order to make the memory they currently
occupy available for quick reuse. When control returns from the method
call, the Java Virtual Machine has made a best effort to reclaim space
from all discarded objects.
The call System.gc() is effectively equivalent to the call:
Runtime.getRuntime().gc()
So, essentially, it's a suggestion to the GC heuristics that right now is a good time to free some memory. For example, say you're writing a game where the framerate is locked to 60FPS. Each frame has a budget of 16.6 (repeating, of course ;)) milliseconds. Say your frame only takes 5ms to run. Usually, you would wait the remaining time with Thread.sleep. However, you could instead opt to call System.gc() first, to tell the VM "hey, I have some extra time -- feel free to clean up while I wait". Of course, you have no guarantee that the garbage collection will take less than the 11.6MS you have remaining! But if done carefully it can help your memory usage and prevent garbage collection from happening at a bad time. Similar principles apply to other kinds of applications -- basically, if you know that your application will have some downtime, you can let the VM know with System.gc() and hopefully prevent the GC from instead deciding to run in the middle of something important.
These methods are provided if someone wants to take hold of garbage collection(which was valid for old JVMs) but its always wise to leave garbage part on JVM specially Modern JVM implementations have highly optimized garbage collectors. Our jobs has made easy by modren JVM implementations so we have to only focus on java code.
Basically you are right saying there is no guarantee that jvm will actually start gc right after your System.gc() call. However gc can take a note of your willing to make collection now and actually run it.
It depends from jvm, but as far as I know hotspot jvm actually runs gc after System.gc() or Runtime.gc(), at least most of the times.
So I would say that not having at least one way to suggest vm to run gc would have been a mistake. There can be different vm implementations, and what if there is a vm which wants to provide possibility to call gc with guarantee that it would actually run after such call, it wouldn't break specification and it might be usefull for some cases, and as I already mentioned hotspot vm most probably wouldn't ignore this call.
You are correct, gc() calls should not be provided in the first place when there is no use case. I can think of at least one positive and two negative points of using explicit GC calls:
If you are building an application where you have little control of JVM options and want to achieve some God level tuning from within the code, you may use an explicit call. But rest assured, that this is not a magic call to get GC done in scenarios where you suddenly expect low load for a few minutes. You may need to put in a lot of effort to achieve that like estimating responsiveness of GC, amount of memory to be collected, etc.
System.gc() or Runtime.getRuntime().gc() may serve as a reminder or suggestion, but it is completely a prerogative of JVM to do so or not. On the contrary, it might not do anything at all upon seeing such request. Reference: Oracle Java
Having said that, it's usually avoided because GC is something which can be controlled and handled via external JVM options rather than from code itself. For example: -XX:-DisableExplicitGC
Related
I know that garbage collection is automated in Java. But I understood that if you call System.gc() in your code that the JVM may or may not decide to perform garbage collection at that point. How does this work precisely? On what basis/parameters exactly does the JVM decide to do (or not do) a GC when it sees System.gc()?
Are there any examples in which case it's a good idea to put this in your code?
In practice, it usually decides to do a garbage collection. The answer varies depending on lots of factors, like which JVM you're running on, which mode it's in, and which garbage collection algorithm it's using.
I wouldn't depend on it in your code. If the JVM is about to throw an OutOfMemoryError, calling System.gc() won't stop it, because the garbage collector will attempt to free as much as it can before it goes to that extreme. The only time I've seen it used in practice is in IDEs where it's attached to a button that a user can click, but even there it's not terribly useful.
The only example I can think of where it makes sense to call System.gc() is when profiling an application to search for possible memory leaks. I believe the profilers call this method just before taking a memory snapshot.
You have no control over GC in java -- the VM decides. I've never run across a case where System.gc() is needed. Since a System.gc() call simply SUGGESTS that the VM do a garbage collection and it also does a FULL garbage collection (old and new generations in a multi-generational heap), then it can actually cause MORE cpu cycles to be consumed than necessary.
In some cases, it may make sense to suggest to the VM that it do a full collection NOW as you may know the application will be sitting idle for the next few minutes before heavy lifting occurs. For example, right after the initialization of a lot of temporary object during application startup (i.e., I just cached a TON of info, and I know I won't be getting much activity for a minute or so). Think of an IDE such as eclipse starting up -- it does a lot to initialize, so perhaps immediately after initialization it makes sense to do a full gc at that point.
The Java Language Specification does not guarantee that the JVM will start a GC when you call System.gc(). This is the reason of this "may or may not decide to do a GC at that point".
Now, if you look at OpenJDK source code, which is the backbone of Oracle JVM, you will see that a call to System.gc() does start a GC cycle. If you use another JVM, such as J9, you have to check their documentation to find out the answer. For instance, Azul's JVM has a garbage collector that runs continuously, so a call to System.gc() won't do anything
Some other answer mention starting a GC in JConsole or VisualVM. Basically, these tools make a remote call to System.gc().
Usually, you don't want to start a garbage collection cycle from your code, as it messes up with the semantics of your application. Your application does some business stuff, the JVM takes care of memory management. You should keep those concerns separated (don't make your application do some memory management, focus on business).
However, there are few cases where a call to System.gc() might be understandable. Consider, for example, microbenchmarks. No-one wants to have a GC cycle to happen in the middle of a microbenchmark. So you may trigger a GC cycle between each measurement to make sure every measurement starts with an empty heap.
You need to be very careful if you call System.gc(). Calling it can add unnecessary performance issues to your application, and it is not guaranteed to actually perform a collection. It is actually possible to disable explicit System.gc() via the java argument -XX:+DisableExplicitGC.
I'd highly recommend reading through the documents available at Java HotSpot Garbage Collection for more in depth details about garbage collection.
System.gc() is implemented by the VM, and what it does is implementation specific. The implementer could simply return and do nothing, for instance.
As for when to issue a manual collect, the only time when you may want to do this is when you abandon a large collection containing loads of smaller collections--a
Map<String,<LinkedList>> for instance--and you want to try and take the perf hit then and there, but for the most part, you shouldn't worry about it. The GC knows better than you--sadly--most of the time.
If you use direct memory buffers, the JVM doesn't run the GC for you even if you are running low on direct memory.
If you call ByteBuffer.allocateDirect() and you get an OutOfMemoryError you can find this call is fine after triggering a GC manually.
Most JVMs will kick off a GC (depending on the -XX:DiableExplicitGC and -XX:+ExplicitGCInvokesConcurrent switch). But the specification is just less well defined in order to allow better implementations later on.
The spec needs clarification: Bug #6668279: (spec) System.gc() should indicate that we don't recommend use and don't guarantee behaviour
Internally the gc method is used by RMI and NIO, and they require synchronous execution, which: this is currently in discussion:
Bug #5025281: Allow System.gc() to trigger concurrent (not stop-the-world) full collections
Garbage Collection is good in Java, if we are executing Software coded in java in Desktop/laptop/server. You can call System.gc() or Runtime.getRuntime().gc() in Java.
Just note that none of those calls are guaranteed to do anything. They are just a suggestion for the jvm to run the Garbage Collector. It's up the the JVM whether it runs the GC or not. So, short answer: we don't know when it runs. Longer answer: JVM would run gc if it has time for that.
I believe, the same applies for Android. However, this might slow down your system.
Normally, the VM would do a garbage collection automatically before throwing an OutOfMemoryException, so adding an explicit call shouldn't help except in that it perhaps moves the performance hit to an earlier moment in time.
However, I think I encountered a case where it might be relevant. I'm not sure though, as I have yet to test whether it has any effect:
When you memory-map a file, I believe the map() call throws an IOException when a large enough block of memory is not available. A garbage collection just before the map() file might help prevent that, I think. What do you think?
we can never force garbage collection. System.gc is only suggesting vm for garbage collection, however, really what time the mechanism runs, nobody knows, this is as stated by JSR specifications.
There is a LOT to be said in taking the time to test out the various garbage collection settings, but as was mentioned above it usually not useful to do so.
I am currently working on a project involving a memory-limited environment and a relatively large amounts of data--there are a few large pieces of data that push my environment to its limit, and even though I was able to bring memory usage down so that in theory it should work just fine, I would still get heap space errors---the verbose GC options showed me that it was trying to garbage collect, but to no avail. In the debugger, I could perform System.gc() and sure enough there would be "plenty" of memory available...not a lot of extra, but enough.
Consequently, The only time my application calls System.gc() is when it is about to enter the segment of code where large buffers necessary for processing the data will be allocated, and a test on the free memory available indicates that I'm not guaranteed to have it. In particular, I'm looking at a 1gb environment where at least 300mb is occupied by static data, with the bulk of the non-static data being execution-related except when the data being processed happens to be at least 100-200 MB at the source. It's all part of an automatic data conversion process, so the data all exists for relatively short periods of time in the long run.
Unfortunately, while information about the various options for tuning the garbage collector is available, it seems largely an experimental process and the lower level specifics needed to understand how to handle these specific situations are not easily obtained.
All of that being said, even though I am using System.gc(), I still continued to tune using command line parameters and managed to improve the overall processing time of my application by a relatively significant amount, despite being unable to get over the stumbling block posed by working with the larger blocks of data. That being said, System.gc() is a tool....a very unreliable tool, and if you are not careful with how you use it, you will wish that it didn't work more often than not.
If you want to know if your System.gc() is called, you can with the new Java 7 update 4 get notification when the JVM performs Garbage Collection.
I am not 100% sure that the GarbageCollectorMXBean class was introduces in Java 7 update 4 though, because I couldn't find it in the release notes, but I found the information in the javaperformancetuning.com site
I can't think of a specific example when it is good to run explicit GC.
In general, running explicit GC can actually cause more harm than good, because an explicit gc will trigger a full collection, which takes significantly longer as it goes through every object. If this explicit gc ends up being called repeatedly it could easily lead to a slow application as a lot of time is spent running full GCs.
Alternatively if going over the heap with a heap analyzer and you suspect a library component to be calling explicit GC's you can turn it off adding: gc=-XX:+DisableExplicitGC to the JVM parameters.
Accroding to Thinking in Java by Bruce Eckel, one use case for explicit System.gc() call is when you want to force finalization, i.e. the call to finalize method.
while system.gc works,it will stop the world:all respones are stopped so garbage collector can scan every object to check if it is needed deleted. if the application is a web project, all request are stopped until gc finishes,and this will cause your web project can not work in a monent.
I am trying to understand the garbage collector method.
"In Java, your program must call the garbage collector method
frequently; otherwise your program will be overrun with garbage
objects"
I believe this is false because the program should do this automatically, running in the background correct?
Correct. In fact, there is no garbage-collector method (System.gc() is a hint that now might be a good time to garbage collect, but it's nothing more). The JVM, if it implements garbage collection (and all Java SE and Java EE ones do), will collect based on its own rules, which usually include concurrently cleaning up short-lived objects, and doing a major collection when memory starts getting low or fragmented.
While in general calling System.gc() is considered bad, bad, bad, very bad practice, in some cases this may prevent the out of memory error. This is mostly when you allocate lots of objects in a very rapid succession and have time moments when many of these are no longer referenced and can be dropped. While System.gc() is just a hint, sometimes the system may need this hint. Alternatively you may rethink you algorithm.
These situations are, however, increasingly rare with the newer Java versions; used to be more frequent in the past. The official point of view is never call garbage collector manually.
The method System.gc() does not necessarily call the Garbage Collector. Garbage Collection is dependent on JVM implementation. For Example a Linux JVM may actually call GC when you do System.gc() a Windows JVM may not.
Lets say you have too many unreachable objects in memory but you still have enough Heap space left so the JVM may decide not to run the GC thread. So conclusion "There is no guaruntee that the GC thread will run when you call System.gc() and it is not necessary to call it."
This is one of Java's main advantage the developer need not worry about Memory management and stuff. unlike C++ where you have to do something like
free(obj);
I need to to know whether the Garbage Collector in Java works on its own or we do need to start it.
It works on its own. You can "suggest" that it run, but that's about it.
The GC is a deamon thread that's started with your JVM and ends when your JVM ends (JVM is stoped if no more non-deamon threads exist).
It runs in background and kicks into action when/if needed. The JVM decides when it runs and you can "request" it to run with System.gc().
But I should mention that you must not write your code to depend on the GC to run (finalizers in Java are not like destructors in C++). People tend to count to much on the GC and then forget about it which is a no-no and leads to memory leaks and hard to find bugs.
What you can count on is that before you get a java.lang.OutOfMemoryError, the GC kiked into action and did its best.
It works on its own according to an optimized algorithm to get the optimal performance. You can perform a force garbage collection but it is not recommended because it can block the normal Garbage collection pattern reducing the actual performance.
You should read this Old SO Discussion on a related topic.
Yes, garbage collection is automatically handelled by Java.
When an object is no longer referred to by any variable, Java automatically reclaims memory used by that object. This is known as garbage collection.
Still the method
System.gc() method may be used to call it explicitly.
The only occasion I know of where you have to call System.gc() is when you are creating lots of Direct ByteBuffers. For heap memory, an OutOfMemoryError will only occur after a Full GC, however for direct memory, if you run out (even though there might be buffers which are not referenced), no GC is called and so you might have to call it yourself before trying again.
I would hope this is something which is fixed in future versions of Java.
(This is probably just repeating what other answers were trying to say ... However, it is worth saying this clearly.)
The Java garbage collector runs automatically as required, and there is no need to start it.
There is a static method (System.gc()) that an application can call to request that the garbage collector run "now". However:
The JVM can be configured to pay no attention to this request.
It is generally a bad idea to make this request because it can significantly degrade garbage collector performance. Generally speaking, the best time to run the garbage collector is when there is lots of garbage to be collected, and only the JVM knows when that is likely to be.
EDIT - the cure for large garbage collection latencies is to change the JVM's garbage collector properties to select the low latency collector. Calling System.gc() is not the way to deal with this in a modern JVM.
I have a piece of code that load a very big image in memory. So it seemed like a reasonable thing to call
System.gc();
before loading the image. From what I can tell it works with no issues.
Yesterday i decided to use a pretty useful piece of software called FindBugs that scans your code and reports back issues that might cause bugs or generally not advised strategies. The problem is that this piece of code i mentioned gets reported. The description is this:
... forces garbage collection;
extremely dubious except in
benchmarking code
And it goes on to elaborate :
Code explicitly invokes garbage
collection. Except for specific use in
benchmarking, this is very dubious.
In the past, situations where people
have explicitly invoked the garbage
collector in routines such as close or
finalize methods has led to huge
performance black holes. Garbage
collection can be expensive. Any
situation that forces hundreds or
thousands of garbage collections will
bring the machine to a crawl.
So my question is : Is it NOT OK to programmatically call the garbage collector in such a case? My code only calls it once and the method that it is in gets used rarely. And if it is not OK to call it then what should you do in a case where you need as much memory as possible before doing a very memory intensive operation and you need to free as much memory as posible prior to it?
Did you get any performance improvements with the System.gc()?
I don't think so, since you probably dont have a lot of objects that needs to be collected before you load the image.
Usually modern garbage collectors know best when to run, so you shouldnt force a collection, unless you have a really really good reason to. (for example a benchmarking application as suggested by that plugin)
btw: Calling System.gc() recommends the VM to perform a "full" or "large" collection, which means that all threads are stopped shortly.
Otherwise it will probably only make "small" garbage collections, which don't stop all threads.
Run your program with -verbose:gc to see how many bytes are collected.
There is also lots of technical information on garbage collection here:
http://java.sun.com/developer/technicalArticles/Programming/GCPortal/
Typically the GC is smarter than you, so it's better to let it run whenever the runtime decides. If the runtime needs memory, it'll run the GC itself
It's fine to call the garbage collector, you don't get any "problems" from it.
However, I doubt it will significently boost performance, unless that call also deals with defragging the allocated data. I don't know that.
What you should do in this case is profile the code. Run it several times, see what sort of results you get.
Typically, you should not interfere with the garbage collector. If it's necessary to free some memory before loading the image, then the garbage collector will do it for you.
Regardless, if you're only doing it once, it's probably not going to affect your performance drastically. Things done in loops are far more important.
You already got plenty of good advice, which I will try not to reiterate.
If you actually get problems with the GC, like full stops of your application for a second, do the following:
1. check that there aren't any calls to System.gc();
2. check out the various options for configuring the gc. There are tons of those around, and they are much more helpful, then forcing gc.
Ensure that the large objects can be gc'ed as early as possible. I.e. set variables to null and/or let them fall out of scope. THis helps!
If a memory allocation fails, a GC cycle is initiated and the allocation is tried again.
Generally, no. It isn't appropriate to call System.gc(). However, I have had a few cases where it made sense.
In the software I write, there is a built-in performance tracking layer. It is mostly used during automated testing, but can be used in the field for diagnostic purposes. Between tests or after specific runs we will call System.gc a few times and then record the memory still present. It provides us with a basic memory foot print benchmark for watching memory consumption trend lines over time. While this can be done with some of the external JVM interfaces, it was easier to do it in place and exact numbers were not required.
On a much older system, we could have upwards of 72 separate JVMs (yeah, 72, there was a good reason for it at the time of construction). In that system, leaving the heap to free float on all 72 JVMs could yield some excessive (well beyond physical memory) total memory consumption. System.gc() was called between heavy data exercises to try and keep the JVM closer to average to keep the heap from growing (capping the heap could have been another direction, but then it would have required the implementers to configure more per site and be more aware of what was happening under the hood to get it right and not have the system fail under load).
I know that garbage collection is automated in Java. But I understood that if you call System.gc() in your code that the JVM may or may not decide to perform garbage collection at that point. How does this work precisely? On what basis/parameters exactly does the JVM decide to do (or not do) a GC when it sees System.gc()?
Are there any examples in which case it's a good idea to put this in your code?
In practice, it usually decides to do a garbage collection. The answer varies depending on lots of factors, like which JVM you're running on, which mode it's in, and which garbage collection algorithm it's using.
I wouldn't depend on it in your code. If the JVM is about to throw an OutOfMemoryError, calling System.gc() won't stop it, because the garbage collector will attempt to free as much as it can before it goes to that extreme. The only time I've seen it used in practice is in IDEs where it's attached to a button that a user can click, but even there it's not terribly useful.
The only example I can think of where it makes sense to call System.gc() is when profiling an application to search for possible memory leaks. I believe the profilers call this method just before taking a memory snapshot.
You have no control over GC in java -- the VM decides. I've never run across a case where System.gc() is needed. Since a System.gc() call simply SUGGESTS that the VM do a garbage collection and it also does a FULL garbage collection (old and new generations in a multi-generational heap), then it can actually cause MORE cpu cycles to be consumed than necessary.
In some cases, it may make sense to suggest to the VM that it do a full collection NOW as you may know the application will be sitting idle for the next few minutes before heavy lifting occurs. For example, right after the initialization of a lot of temporary object during application startup (i.e., I just cached a TON of info, and I know I won't be getting much activity for a minute or so). Think of an IDE such as eclipse starting up -- it does a lot to initialize, so perhaps immediately after initialization it makes sense to do a full gc at that point.
The Java Language Specification does not guarantee that the JVM will start a GC when you call System.gc(). This is the reason of this "may or may not decide to do a GC at that point".
Now, if you look at OpenJDK source code, which is the backbone of Oracle JVM, you will see that a call to System.gc() does start a GC cycle. If you use another JVM, such as J9, you have to check their documentation to find out the answer. For instance, Azul's JVM has a garbage collector that runs continuously, so a call to System.gc() won't do anything
Some other answer mention starting a GC in JConsole or VisualVM. Basically, these tools make a remote call to System.gc().
Usually, you don't want to start a garbage collection cycle from your code, as it messes up with the semantics of your application. Your application does some business stuff, the JVM takes care of memory management. You should keep those concerns separated (don't make your application do some memory management, focus on business).
However, there are few cases where a call to System.gc() might be understandable. Consider, for example, microbenchmarks. No-one wants to have a GC cycle to happen in the middle of a microbenchmark. So you may trigger a GC cycle between each measurement to make sure every measurement starts with an empty heap.
You need to be very careful if you call System.gc(). Calling it can add unnecessary performance issues to your application, and it is not guaranteed to actually perform a collection. It is actually possible to disable explicit System.gc() via the java argument -XX:+DisableExplicitGC.
I'd highly recommend reading through the documents available at Java HotSpot Garbage Collection for more in depth details about garbage collection.
System.gc() is implemented by the VM, and what it does is implementation specific. The implementer could simply return and do nothing, for instance.
As for when to issue a manual collect, the only time when you may want to do this is when you abandon a large collection containing loads of smaller collections--a
Map<String,<LinkedList>> for instance--and you want to try and take the perf hit then and there, but for the most part, you shouldn't worry about it. The GC knows better than you--sadly--most of the time.
If you use direct memory buffers, the JVM doesn't run the GC for you even if you are running low on direct memory.
If you call ByteBuffer.allocateDirect() and you get an OutOfMemoryError you can find this call is fine after triggering a GC manually.
Most JVMs will kick off a GC (depending on the -XX:DiableExplicitGC and -XX:+ExplicitGCInvokesConcurrent switch). But the specification is just less well defined in order to allow better implementations later on.
The spec needs clarification: Bug #6668279: (spec) System.gc() should indicate that we don't recommend use and don't guarantee behaviour
Internally the gc method is used by RMI and NIO, and they require synchronous execution, which: this is currently in discussion:
Bug #5025281: Allow System.gc() to trigger concurrent (not stop-the-world) full collections
Garbage Collection is good in Java, if we are executing Software coded in java in Desktop/laptop/server. You can call System.gc() or Runtime.getRuntime().gc() in Java.
Just note that none of those calls are guaranteed to do anything. They are just a suggestion for the jvm to run the Garbage Collector. It's up the the JVM whether it runs the GC or not. So, short answer: we don't know when it runs. Longer answer: JVM would run gc if it has time for that.
I believe, the same applies for Android. However, this might slow down your system.
Normally, the VM would do a garbage collection automatically before throwing an OutOfMemoryException, so adding an explicit call shouldn't help except in that it perhaps moves the performance hit to an earlier moment in time.
However, I think I encountered a case where it might be relevant. I'm not sure though, as I have yet to test whether it has any effect:
When you memory-map a file, I believe the map() call throws an IOException when a large enough block of memory is not available. A garbage collection just before the map() file might help prevent that, I think. What do you think?
we can never force garbage collection. System.gc is only suggesting vm for garbage collection, however, really what time the mechanism runs, nobody knows, this is as stated by JSR specifications.
There is a LOT to be said in taking the time to test out the various garbage collection settings, but as was mentioned above it usually not useful to do so.
I am currently working on a project involving a memory-limited environment and a relatively large amounts of data--there are a few large pieces of data that push my environment to its limit, and even though I was able to bring memory usage down so that in theory it should work just fine, I would still get heap space errors---the verbose GC options showed me that it was trying to garbage collect, but to no avail. In the debugger, I could perform System.gc() and sure enough there would be "plenty" of memory available...not a lot of extra, but enough.
Consequently, The only time my application calls System.gc() is when it is about to enter the segment of code where large buffers necessary for processing the data will be allocated, and a test on the free memory available indicates that I'm not guaranteed to have it. In particular, I'm looking at a 1gb environment where at least 300mb is occupied by static data, with the bulk of the non-static data being execution-related except when the data being processed happens to be at least 100-200 MB at the source. It's all part of an automatic data conversion process, so the data all exists for relatively short periods of time in the long run.
Unfortunately, while information about the various options for tuning the garbage collector is available, it seems largely an experimental process and the lower level specifics needed to understand how to handle these specific situations are not easily obtained.
All of that being said, even though I am using System.gc(), I still continued to tune using command line parameters and managed to improve the overall processing time of my application by a relatively significant amount, despite being unable to get over the stumbling block posed by working with the larger blocks of data. That being said, System.gc() is a tool....a very unreliable tool, and if you are not careful with how you use it, you will wish that it didn't work more often than not.
If you want to know if your System.gc() is called, you can with the new Java 7 update 4 get notification when the JVM performs Garbage Collection.
I am not 100% sure that the GarbageCollectorMXBean class was introduces in Java 7 update 4 though, because I couldn't find it in the release notes, but I found the information in the javaperformancetuning.com site
I can't think of a specific example when it is good to run explicit GC.
In general, running explicit GC can actually cause more harm than good, because an explicit gc will trigger a full collection, which takes significantly longer as it goes through every object. If this explicit gc ends up being called repeatedly it could easily lead to a slow application as a lot of time is spent running full GCs.
Alternatively if going over the heap with a heap analyzer and you suspect a library component to be calling explicit GC's you can turn it off adding: gc=-XX:+DisableExplicitGC to the JVM parameters.
Accroding to Thinking in Java by Bruce Eckel, one use case for explicit System.gc() call is when you want to force finalization, i.e. the call to finalize method.
while system.gc works,it will stop the world:all respones are stopped so garbage collector can scan every object to check if it is needed deleted. if the application is a web project, all request are stopped until gc finishes,and this will cause your web project can not work in a monent.