views:

348

answers:

9

For example I such a code

... get some memory and lose all the pointers to that memory so that System.gc(); can collect it.

call System.gc();

do some other tasks;


Here does the "do some other tasks;" and "System.gc();" works in paralel or does the "do some other tasks;" waits for "System.gc();" to be executed

Thank you

A: 

"Do some other task" waits for System.gc() to execute and return.

Amarghosh
I hope ur correct. because I assumed so and wrote my code accordingly.R u sure of it?
ogzylz
A: 

There is no way to know. Calling System.gc() does not mean that a garbage collection is performed at that very second, it is merely scheduled. It is up to the JVM to perform the garbage collection at a suitabe time.

Eric Eijkelenboom
From the API documentation for `System.gc()`, "When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects."
Matthew T. Staebler
Yes I have read that too but, what does "best effort" means? Does it creates a new thread for that process. Or do my "do some task" waits for System.gc()? this is not clear
ogzylz
+7  A: 

You probably shouldn't be using System.gc(). A common misconception with C/C++ users coming over to java is they think they need to tell the virtual machine when it can perform garbage collection. The reality is that the garbage collector is highly optimized and performs this task by itself when it feels it is best to do so. Calling System.gc() is not usually recommended.

If you do call System.gc() though, it will 'recommend' to the system to perform garbage collection. It may not actually perform a collection though it usually does. If it runs in another thread depends on the actual collection algorithm. The default one will block everything while it runs. So it may run in separate threads but it will block your current execution when it does.

Chris Dail
But,I have such a contraint. -Xmx3000mfirst I get 2.4g secondly I get 400m more and then lost all the pointer to that memory space.third I want to release 400m that I took in second immediately so that I can get another 400m If I dont call gc(); immediately I fail to get another 400m. ı think for that reason My iterative algoritm stops at some iterations in the servers.
ogzylz
If this is correct : "So it may run in separate threads but it will block your current execution when it does." I am safe. thax
ogzylz
@ogzylz It does not work like that. You do not need to call gc() to free memory. The JVM will continue to run and likely creep toward the 3g mark before performing a gc(). With 3g to work in, it does not need to run gc() often (increases performance). Do not worry if you see your process consuming close to 3g of memory. That is normal.
Chris Dail
FYI : Yes your answer is correct. I figured out where I was wrong. First I run a program with -Xmx3600m. Then, I ran a second program with also -Xmx3600m. JVM enabled me to run these programs. But a 32 bit JVM can only adress up to 4gb of memory. When these two program's total memory allocation exceeded 4gb, I most probably got OutOfMemoryError (I dont know if it was the case for sure, because i didnt took log properly) when I ran these programs one by one it worked well and got no problem
ogzylz
continued : That's why I thought System.gc() doesnt work as you said and I need to call it myself. All in all, I better switch to a 64 bit machine ASAP.
ogzylz
I recognized that this previous justification was not correct either. I was doing wrong with using the Threads and synchronization. I solved that problem. The initial problem has nothing with using System.gc() or memory problems.
ogzylz
+4  A: 

It's usually synchronous, but not guaranteed.

Actually is neither guaranteed that a collection will effectively take place since the JVM will decide if it makes sense and what kind of garbage collection use.

If you need additional info you can launch your program with -verbosegc flag..

In any case the garbage collection is something that it issued automatically by the JVM without any specified calls, invoking System.gc() is just a hint you give to let it know that it may start a collection.

Jack
thank for this -verbosegc It really helped a lot
ogzylz
+1  A: 

How the Garbage collection is executed is up to the JVM-implementation. Usual implementations may stop all threads, to collect memory globally, stop only one thread to collect memory local for this thread for instance. Read more about garbage collection from Sun and in this older but good article.

Mnementh
thanks. those a quite informative
ogzylz
+1  A: 

As Eric Eijkelenboom pointed out, calling this method does not mean the the Garbage Collector will execute immediately. Actually you don't know if it will be called at all...

In your case (judging from the comment on Amarghosh's answer) you need to free up some memory before you do something that requires a lot of RAM am i right? In that case you don't need to worry. If there is enough memory to be garbage collected it will be done automatically when you try to allocate it.

Savvas Dalkitsis
Yes ur right. I recognized that I was doing wrong with using the Threads and synchronization. I solved that problem. The initial problem has nothing with using System.gc() nor memory problems
ogzylz
A: 

Hi,

the javadoc tells http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#gc() : "When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects."

So I would say that "do some other tasks;" waits for "System.gc();" to be executed!

No parallelism is used - and that's not good for a Java application. In fact, it's never a good idea to call/force the Garbage Collector. It must be reserve to extreme cases with no other solutions...

Bye, Alban.

Alban Soupper
yes I have such an extreme case. I will repeat my answer to another anser here again : But, I have such a contraint. -Xmx3000m first I get 2.4g secondly I get 400m more and then lost all the pointer to that memory space. third I want to release 400m that I took in second immediately so that I can get another 400m If I dont call gc(); immediately I fail to get another 400m. ı think for that reason My iterative algoritm stops at some iterations in the servers
ogzylz
+3  A: 

The exact behavior here depends entirely on the JVM implementation. In spec (that is what a proper JVM implementation needs to provide you), it can happen in parallel, it can happen first before your code executes, or it can not happen at all.

In practice, my observation on JVMs I have happened to observe is that it runs immediately in a separate thread. However, in some cases multiple calls spawn multiple threads, sometimes it queues the requests on one thread. The Garbage collection launched was always a "stop-the-world" type (that is it was very complete and slowed or paused the application).

However, given your comment to @Chris Dail, your underlying problem isn't the behavior of a System.gc() call. Calling System.gc() can have some uses. It can be used clear memory so you can get a sense of how large the footprint of the application actually is currently. It can also be used as a strategy to ensure that a stop-the-world garbage collection happens earlier so that it "stops the world" for a shorter amount of time because there is less memory to clear. (I should note that as JVM's get more and more sophisticated this kind of thing is less and less necessary, and actually becomes counter-productive).

What it does not do however, is in any way solve an OutOfMemoryError. The JVM will not give you an OutOfMemoryError until it has garbage collected to the best of its ability. Calling System.gc does not change that. If you have an OutOfMemoryError it is likely because you are holding reference to objects in ways that you don't really need, but that are preventing those Objects memory from being reclaimed.

Yishai
FYI : Yes your answer is correct. I figured out where I was wrong. First I run a program with -Xmx3600m. Then, I ran a second program with also -Xmx3600m. JVM enabled me to run these programs. But a 32 bit JVM can only adress up to 4gb of memory. When these two program's total memory allocation exceeded 4gb, I most probably got OutOfMemoryError (I dont know if it was the case for sure, because i didnt took log properly) when I ran these programs one by one it worked well and got no problem.
ogzylz
continued : That's why I thought System.gc() doesnt work as you said and I need to call it myself. All in all, I better switch to a 64 bit machine ASAP.
ogzylz
@ogzylz, if you need that kind of memory, you need a 64 bit machine and JVM. However, the limit here is the OS as much as the JVM. The JVM requires contiguous address space, and a 32 bit OS likely cannot give it that kind of memory, and certainly is very limited in what it can give two JVMs that demand that kind of memory.
Yishai
I recognized that this previous justification was not correct either. I was doing wrong with using the Threads and synchronization. I solved that problem. The initial problem has nothing with using System.gc() or memory problems
ogzylz
A: 

According to the Java specification, the thread which calls System.gc() is stopped until the GC has done its deed. Note that this is just a hint, the JVM is free to ignore it, and Sun's JVM actually has a command-line switch (-XX:-DisableExplicitGC) to that effect. With this switch, System.gc() does nothing and returns immediately.

Either way, nothing in the specification prevents other threads from running. This depends on the GC algorithm; Sun's JVM includes several, some of which being able to run concurrently with the applicative threads for most of their work.

As was pointed out by others, the net effect of calling System.gc() explicitly is, most of the time, to decrease performance. If you feel that you must call that method, then chances are that you are doing something wrong.

Thomas Pornin
yes ur right. I have recognised where I was wrong. For futher detail why I was wrong, you can read the response that I provide to the Chris Dail's answer. Thnx
ogzylz