I don't know. My guess is that at some point early on, the System.gc() was useful. But as I understand it the GC algorithms have become so sophisticated that it's just about impossible to out-think them.
So calling this will tell the JVM to consider it, but the JVM will almost without a doubt ignore it.
[Fred]: I don't know. My guess is that at some point early on, the System.gc() was useful.
Yes, I think it was more useful initially, as gc() wasn't as well optimized to work without it. Also, many people just didn't trust gc() that much and wanted more control. So Sun gave them some, even if it wasn't absolute.
[Fred]: So calling this will tell the JVM to consider it, but the JVM will almost without a doubt ignore it.
I don't agree with this at all. My experience is that the standard JVMs from Sun (as well as IBM and Apple) will indeed react to the System.gc() command and free up some memory. They often don't get all of what should be available; in some cases they may not get any of it. As everyone has heard many times, the effectiveness of gc() is not guaranteed. However, that doesn't mean it doesn't do anything. You can observe this by running with the java -verbose:gc option, which prints additional messages whenever gc is active. Thus you can see gc() actually working, in many cases.
The reason we're not supposed to use gc() is not because it doesn't do anything - it's because what it does is usually out-of-sync with what the regularly scheduled garbage collection is trying to do. Which is largely because of JVM optimizations made after Java was initially released.
[Campbell]: do we think it and other rarely-used methods (eg Object.finalize()) are there because that sort of activity was required in C++?
Sort of, yes. C/C++ programmers were used to being able to manage memory (because they had to), so System.gc() was sort of there to placate people who were used to more control, I think. And C++ programmers were used to having to call destructors, so Java's designers included a mechanism for performing some cleanup tasks in finalize(). Unfortunately they apparently didn't have time to fully evaluate the usefulness of this idea, and it turns out to be not very good. But we're still stuck with it in the API because Sun doesn't want to break backwards compatibility.
To answer Rajesh's original question, the uses of System.gc() are pretty rare nowadays, but there are a few. The main thing I use it for is in cases where I want to test the memory usage of a program, and for testing purposes only I don't care about the performance; I just want to see how much memory is used. So I may do something like this:
Again, this is horrible for performance; it's only useful for measurement of memory usage. Why do it ten times in a row? Well, because I've observed that one, two, or three times are often not enough. (Try it and look at the output using -verbose:gc.) Usually by 4, 5, or 6 the additional gc() calls are having no effect. But I choose 10 times just to be extra confident.
On rare occasions, you may see other uses for System.gc() if you've got a program where the automatic gc() is occurring at an inconvenient time. Sometimes it may be useful to cause it to occur earlier, if there's a time when the user will notic the effect of gc less. For example, in a video game, you might want to do gc() in between levels, becaus ethe user doesn't expect to be able to play then. Better than having the game slow down drastically in the midst of a big action sequence. Even here though, there's a good chance that you will just make any performance problems worse, not better. I'm not really recommending using gc(), just noting that it's possible it may be useful. [ May 29, 2007: Message edited by: Jim Yingst ]