When does garbage collection work in java? - java

I knew that there are a lot of articles about java garbage collection but after searching I don't know exactly "when dose the garbage collection run in a java application?(when the application restart or while it still running)".

Garbage Collector is a dameon thread. A dameon thread runs behind the application. It is started by JVM. The
thread stops when all non-dameon threads stop.
The JVM controls the Garbage Collector; it decides when to run the Garbage Collector. JVM runs
the Garbage Collector when it realizes that the memory is running low. The behavior of GC can
be tuned by passing parameters to JVM.
One can request the Garbage Collection to happen from
within the java program but there is no guarantee that this request will be taken care of by
jvm.Check How to force garbage collection in Java?
Learn More ..

Garbage collection runs regularly alongside the program. It is part of the JVM.
When exactly does it run though? Well, that's unpredictable, version-dependent, and should be treated as if it could run at any time.
When a variable goes out of scope, the application tells the JVM it's done with that piece of memory. Then, when the garbage collector runs it will free those resources for the OS to use.
For example
String capitalizeAll(String s) {
char[] chars = s.toCharArray();
for(int i = 0; i < chars.length; i++)
chars[i] -= 32;
return new String(chars);
}
As soon as the method returns, the char[] chars allocated within the method will go out of scope. The program tells the JVM it's done with those resources and next time GC runs they will be freed.
Interesting stuff though, the JVM takes into account how much the app has told it is ready to be collected. That means that if your app does a lot of unnecessary copying or boxing, JVM will run often and cause your app to take a performance hit.

This is mostly implementation-specific.
The most primitive type of garbage collector, the serial GC will be triggered when it fails to find sufficient free space during an allocation (with generational GCs this usually means the young generation is full). It then suspends the entire JVM by triggering a safepoint on mutator threads and does its work on a single thread, this is called a "stop the world pause"
In this case you can say that GCs can be caused by any allocation.
On top of that some GCs may also do background work concurrently to mutators, such as Hotspot's CMS. But it still needs stop the world pauses for some work, they just tend to be shorter than in the serial GC.
For CMS it's still triggered by allocations but also does some of its work on background thread(s).
Azul Zing's concurrent compacting collector also does - as its name says - concurrent collecting on dedicated threads more or less all the time. It still needs cooperation from the mutator threads but does so without STW pauses.
So this case one could say that the GC is running all the time in the background and does a little work in the foreground.
There are other collectors out there, so this isn't a comprehensive overview. But in general it's an implementation detail, subject to change and not something one should rely on. Some GCs even ignore System.gc() by default because it would mess up their heuristics.

This is from Kathy Sierra and Bert Bates' book SCJP Study Guide:
"The garbage collector is under the control of the JVM. The JVM decides when to
run the garbage collector. From within your Java program, you can ask the JVM to
run the garbage collector, but there are no guarantees, under any circumstances, that the JVM will comply. Left to its own devices, the JVM will typically run the garbage collector when it senses that memory is running low. Experience indicates that when your Java program makes a request for garbage collection, the JVM will usually grant your request in short order, but there are no guarantees. Just when you think you can count on it, the JVM will decide to ignore your request."

Related

Is there any condition when application will never perform Garbage Collection?

Is there any condition when application will never perform Garbage Collection ? Theoretically is it possible to have such application design ?
Yes, there is. Please read about memory leaks in Java. An example is described in Effective Java Item 6: Eliminate obsolete object references
Garbage collection happens on objects which are not referenced anymore in your application.
With Java 11, there is a way to never purposely perform garbage collection, by running your JVM with the newly introduced Epsilon GC, a garbage collector which handles memory allocation but never releases the allocated memory.
There is at least one product in the market that implements high frequency trading using Java and jvm technology.
Obviously, an application that needs to react in microseconds can't afford a garbage collector to kick in and halt the system for arbitrary periods of time.
In this case, the solution was to write the whole application to never create objects that turn into garbage. For example, all input data is kept in fixed byte arrays (that are allocated once at start time) which are then used as buffers for all kinds of processing.
Unless I am mistaken, you can listen to more details on the software engineering radio podcast. I think it should be this episode: http://www.se-radio.net/2016/04/se-radio-episode-255-monica-beckwith-on-java-garbage-collection/
Is there any condition when application will never perform Garbage Collection ?
You can prevent the GC from running by having a Thread which doesn't reach a safe point.
Unless you use a concurrent collector, the GC will only be performed when a memory region, e.g. when the Eden or Tenure spaces fill.
If you make these large enough, and your garbage rate low enough, the GC won't run for long enough that you can either perform a GC overnight, in a maintenance window or restart the process.
Theoretically is it possible to have such application design?
I have worked on applications which GC less than once per day (and some of them are restarted every day)
For example, say you produce 300KB of garbage per second, or 1 GB per hour, with a 24 GB Eden size you can run for a whole day without a collection.
In reality, if you move most of your data off-heap e.g. Chronicle Map or Queue, you might find a 4 GB, can run for a day or even a week with a minor collection.

how many Java Garbage Collector objects?

Can anyone please tell me if we call garbage collector in parallel executing two threads, how many gc objects are created?
There's always only one garbage collector, that runs in it own Thread
There's one garbage collector as others pointed out.
You should not care about the count of the garbage collector objects
or about any details about the garbage collector. This is something
on JVM/system level. All you care about is when to call the garbage
collection explicitly (if you want to do that).
(This is responding to the OP's comments which reveal the nature of the misunderstanding that is at the root of his Question. See the quoted text ...)
yes Runtime is a singleton but when we are calling Runtime.gc(), ...
Correct
... the jvm internally it will created one thread that is garbage colletor(daemon thread).
Incorrect. It does not create a new GC thread. Rather it causes the existing GC thread to wake up and do a garbage collection. Furthermore:
the thread that calls gc() will not return until the garbage collector has completed.
depending on the garbage collector that has been configured, the garbage collector may freeze all other application threads before starting the collection.
... but in this case when we call gc in two different threads at a time, how many GC objects will be created?
None. If two methods call gc() at the same time, the GC will run once on the existing GC thread. Think of the GC as an "engine" that is either running or sleeping at any point in time. Calling gc() will typically cause the GC to start running if it is currently sleeping.
(Actually, I'm simplifying things a bit. CMS and G1 have the complication that the gc() will typically run in parallel with application threads. Another possibility is that the gc() call will be simply ignored. Finally, the GC typical has a variety of modes; e.g. a young generation collection, and a full collection. Calling gc() will start a full collection.)
... but we are saying that GC is daemon thread
Yes (sort of),
The GC may have multiple threads. There is typically a main GC thread, and another thread for handling finalization. And for some kinds of GC, some tasks are performed in parallel using a pool of threads.
and also gc() has native implementation
For mainstream JVMs, yes. (But as a counter-example, in JNode is implemented in Java, albeit using Unsafe methods, etc.)
then what is GC?
It is the "stuff" that does garbage collection. What actually goes on under the hood is JVM specific, and depends on JVM options, etcetera.

java - garbage collection

Why the method call System.gc() doesn't guarantee that the Garbage Collector algorithm will run at that moment? Why it cannot certainly reclaim all unused object's memory whenever it is invoked ?
Forcing object destruction is sign of bad coding so Java might wanted to avoid developers from getting addicted to it.
If Java gives you freedom of forcing of object destruction, improper use of it might have adverse affect of application performance.
This restriction allows you (force you) to put more focus into business logic than memory managemnt
JVM is the best person to decide when memory management is required and how to do it.
You can (should) trust JVM and let it handle things in better way than we can.
Still do you really want to force object destruction? If yes, WHY?
In order to ensure that programs run smoothly within the JVM, the JVM itself manages garbage collection.
Garbage collection has become quite sophisticated. When you ask the system for a GC run, which algorithm are you expecting? A "full GC"? There are multiple heaps, as well; which one is the garbage you are concerned about on? You don't know and this method doesn't indicate.
Suppose calling System.gc() always triggered a full GC. An errant program could easily grind JVM performance to a halt. Defensively, the JVM would want to limit the frequency at which it responded to such calls.
If you are running in a JVM on a non-embedded system (e.g. a server or a desktop computer), there should be no reason for you to concern yourself with any aspect of memory management other than to monitor it and code efficiently.
There are several metrics that are utilized to evaluate garbage collector performance , some of them are:
Throughput—the percentage of total time not spent in garbage collection, considered over long periods of time.
Garbage collection overhead—the inverse of throughput, that is, the percentage of total time spent in
garbage collection.
Pause time—the length of time during which application execution is stopped while garbage collection is occurring.
Frequency of collection—how often collection occurs, relative to application execution.
Footprint—a measure of size, such as heap size.
Promptness—the time between when an object becomes garbage and when the memory becomes
available.
Now If JVM listens to System.gc() like good pet and guarantees to perform action on each System.gc() call, Imagine what would be the performance of application if it is called many times within program.!!??
Throughput will decrease
Garbage Collection overhead will increase.
Application will pause many times as it is busy in recollecting the memory.
If Footprint is large , The garbage Collector would have to scan all memory area for recovering the memory , no matter if there are objects eligible for garbage collection or not.
So , after looking through these points I guess it provides the sufficient reason to JVM to not respond to System.gc on the application choice , but on its own algorithm. And Garbage Collection reclaims all unused object's memory for sure , but its invocation is entirely dependent on JVM own Algorithm rather than on the user's choice.
Source: Memory Management in the Java HotSpot™ Virtual Machine - Sun Microsystems
it cannot certainly reclaim all unused object's memory whenever it is invoked
This assumption of yours is false. In most cases the Garbage Collector could reclaim all unused objects at any point in time. However, if the standard Java library provided a method that would guarantee that, it would put a completely unreasonable burden on the GC subsystem to provide a service that is most of the time useless and could be even damaging.

Is it a memory leak if the garbage collector runs abnormally?

I have developed a J2ME web browser application, it is working fine. I am testing its memory consumption. It seems to me that it has a memory leak, because the green curve that represents the consumed memory of the memory monitor (of the wireless toolkit) reaches the maximum allocated memory (which is 687768 bytes) every 7 requests done by the browser, (i.e. when the end user navigates in the web browser from one page to other for 7 pages) after that the garbage collector runs and frees the allocated memory.
My question is:
is it a memory leak when the garbage collector runs automatically every 7 page navigation?
Do I need to run the garbage collector (System.gc()) manually one time per request to prevent the maximum allocated memory to be reached?
Please guide me, thanks
To determine if it is a memory leak, you would need to observe it more.
From your description, i.e. that once the maximum memory is reached, the GC kicks in and is able to free memory for your application to run, it does not sound like there is a leak.
Also you should not call GC yourself since
it is only an indication
could potentially affect the underlying algorithm affecting its performance.
You should instead focus on why your application needs so much memory in such a short period.
My question is: is it a memory leak when the garbage collector runs automatically every 7 page navigation?
Not necessarily. It could also be that:
your heap is too small for the size of problem you are trying to solve, or
your application is generating (collectable) garbage at a high rate.
In fact, given the numbers you have presented, I'm inclined to think that this is primarily a heap size issue. If the interval between GC runs decreased over time, then THAT would be evidence that pointed to a memory leak, but if the rate stays steady on average, then it would suggest that the rate of memory usage and reclamation are in balance; i.e. no leak.
Do I need to run the garbage collector (System.gc()) manually one time per request to prevent the maximum allocated memory to be reached?
No. No. No.
Calling System.gc() won't cure a memory leak. If it is a real memory leak, then calling System.gc() will not reclaim the leaked memory. In fact, all you will do is make your application RUN A LOT SLOWER ... assuming that the JVM doesn't ignore the call entirely.
Direct and indirect evidence that the default behaviour of HotSpot JVMs is to honour System.gc() calls:
"For example, the default setting for the DisableExplicitGC option causes JVM to honor Explicit garbage collection requests." - http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.express.doc/info/exp/ae/rprf_hotspot_parms.html
"When JMX is enabled in this way, some JVMs (such as Sun's) that do distributed garbage collection will periodically invoke System.gc, causing a Full GC." - http://static.springsource.com/projects/tc-server/2.0/getting-started/html/ch11s07.html
"It is best to disable explicit GC by using the flag -XX:+DisableExplicitGC." - http://docs.oracle.com/cd/E19396-01/819-0084/pt_tuningjava.html
And from the Java 7 source code:
./openjdk/hotspot/src/share/vm/runtime/globals.hpp
product(bool, DisableExplicitGC, false, \
"Tells whether calling System.gc() does a full GC") \
where the false is the default value for the option. (And note that this is in the OS / M/C independent part of the code tree.)
I wrote a library that makes a good effort to force the GC. As mentioned before, System.gc() is asynchronous and won't do anything by itself. You may want to use this library to profile your application and find the spots where too much garbage is being produced. You can read more about it in this article where I describe the GC problem in detail.
That is (semi) normal behavior. Available (unreferenced) storage is not collected until the size of the heap reaches some threshold, triggering a collection cycle.
You can reduce the frequency of GC cycles by being a bit more "heap aware". Eg, a common error in many programs is to parse a string by using substring to not only parse off the left-most word, but also shorten the remaining string by substringing to the right. Creating a new String for the word is not easily avoided, but one can easily avoid repeatedly substringing the "tail" of the original string.
Running System.GC will accomplish nothing -- on most platforms it's a no-op, since it's so commonly abused.
Note that (outside of brain-dead Android) you can't have a true "memory leak" in Java (unless there's a serious JVM bug). What's commonly referred to as a "leak" in Java is the failure to remove all references to objects that will never be used again. Eg, you might keep putting data into a chain and never clear pointers to the stuff on the far end of the chain that is no longer going to be used. The resulting symptom is that the MINIMUM heap used (ie, the size immediately after GC runs) keeps rising each cycle.
Adding to the other excellent answers:
Looks like you are confusing memory leak with garbage collection.
Memory leak is when unused memory cannot be garbage collected because it still has references somewhere (although they're not used for anything).
Garbage collection is when a piece of software (the garbage collector) frees unreferenced memory automatically.
You should not call the garbage collector manually because that would affect its performance.

Garbage Collection in android (Done manually)

I have a strange doubts. I know garbage collector has its own limitation. and if allocation is
bad then it can cause a problem for application to respond in unusual way.
So my question is that is it good programming habit to call forcefully garbage collector (System.gc()) at the end of each activity?
Update
Every one is saying that calling system.gc() not beneficial at all.Then i am wondering why its present here.DVM will decide when to run garbage collector.Then what is need of that method?
Update 2
Thanks community to help me out. But honestly i got knowledge about Garbage collection real Beauvoir from this link Java Performance Optimization
it isn't good programming habit to call forcefully garbage collector (System.gc()) at the end of each activity
Because it is useless,only DVM decide when it should be call although you called it...
System.gc(), which the VM sometimes ignores at whim, is mostly useful in two cases:
you're gobbling up memory like there's no tomorrow (usually with bitmaps).
you suspect a memory leak (such as accidentally holding onto an old Context), and want to put the VM memory in a quiescent state to see if the memory usage is creeping up, for debugging.
Under nominal circumstances, one should not use it.
I really think it depends on your situation.
Because the heap is generational, the GC may not get rid of certain large objects or bitmaps on its first pass, and its heuristics may not indicate that additional garbage collection is necessary, but there are definitely scenarios where the heuristic could be wrong, and we as the developers have knowledge of a pattern, or can predict usage that the GC cannot, and therefore calling system.gc() will benefit us.
I have seen this before in specific scenarios such as dealing with map tiling or other graphic intensive behaviors, where the native GC in Android (even on 3.0+ devices), doesn't get it right, resulting in Out of Memory errors. However, by adding a few GC calls, the Out of Memory errors are prevented, and the system continues to process albeit at a slower rate (due to garbage collection). In graphic intensive operations, this usually is that state desired (a little lag) over the application crashing because it cannot load additional resources into memory.
My only explanation for why this happens in certain scenarios appears to be timing. If user operations are slow, then the native Android GC seems to do great. However, if your user is scrolling fast, or zooming quickly, this is where I have seen the Android GC lag behind, and a few well thought out System.gc() have resulted in my applications not crashing.
calling System.gc(), doesn't do any harm. but you cant be sure that it will be of some use. because you ask the DVM to do garbage collection, but can't command it... Its dependent totally on DVM. It calls when memory is running out or may be at any time..
I tried putting System.gc() on the line before the lines where I created my bitmap in my Android app. The garbage collector freed up several megabytes in some cases and put and end to my OutOfMemoryError conditions. It did not interfere with the normal garbage collection one bit but it did make my app run faster.
No; if the system needs memory, it will call GC on its own.
Any memory used by an instance, that isn't referenced anywhere else, will become eligible for GC when the instance goes away.
Memory used by the instance itself, if no longer referenced, is also eligible for GC. You can do a code review or profiling to see if you're holding on to memory unnecessarily, but that's a different issue.
Calling GC manually is a bad coding habit...
The Developer docs on RAM usage state:
...
GC_EXPLICIT
An explicit GC, such as when you call gc() (which you should avoid calling and instead trust the GC to run when needed).
...
I've highlighted the most important and relevant part here in bold.
It is possible to ask the Android JVM to run the garbage collector by calling System.gc(). As the documentation states:
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.
Emphasis added!
Some care is needed in interpreting "best effort" in the final sentence:
The "best effort" might be to ignore the "suggestion" entirely. Some JVMs have a configuration option to totally ignore System.gc() calls.
The "best effort" may or may not amount to a full garbage collection. That is an implementation detail.
But the bottom line is that you cannot force the GC to run.
Calling System.gc() is generally a bad idea. It makes your application inefficient, and it may introduce unwanted and unnecessary GC pauses.
The inefficiency issue comes down to the way that modern garbage collectors behave. A garbage collector's work has two parts1:
Finding the objects that are reachable.
Dealing with the objects that are not reachable.
The first part involves traversing reference chains and and marking the graph of objects starting at the GC roots. This work is proportional to the number of reachable objects.
The second part can be handled in a couple of ways, but it will typically be proportional to the size of the reachable objects.
Thus the overall cost of a GC run (in CPU time) depends mostly in the amount of non-garbage. But the benefit of the work performed is the amount of space that you managed to reclaim.
To maximize efficiency, you need to run the GC when the benefit of running the GC is at its highest; i.e. when the heap is close to full. But the problem is that if you call System.gc() you may be requesting a garbage collection when there is lots of free space.
Every one is saying that calling system.gc() not beneficial at all. Then I am wondering why its present here. DVM will decide when to run garbage collector. Then what is need of that method?
It is there for largely historical reasons. The method was present in the System class in Java 1.0. Removing it now would break a lot of legacy code. As for why gc() was included in the first place, the decision was made a long, long time ago, and we were not "in the room" when it was made. My guess is that the decision makers (in ~1995):
were a bit too optimistic about how GC technology would develop,
didn't anticipate that naive programmers would try to use gc() calls to solve memory leaks and other bugs, and / or
were simply too rushed to think too hard about it.
There are also a couple of scenarios where calling System.gc() is beneficial. One such scenario is when your application is about to start a "phase" where unscheduled GC pauses are going to give a particularly bad user experience. By running System.gc() you can take the "performance hit" at a point in time where it matters less; e.g. during a user initiated pause or while switching levels in a game.
But I don't think the above scenario corresponds to your "at the end of every activity".
The final thing to note is that calling System.gc() manually does not prevent normal OOMEs. A normal OOME is typically thrown then the JVM decides there is not enough free heap space to continue. This decision is made immediately after running a (full) GC. Running System.gc() manually won't make any difference to the decision making.
Furthermore, calling System.gc() will not cure normal2 memory leaks. If your application has a memory leak, you actually have a situation where a bunch of objects are reachable when they shouldn't be. But since they are reachable, the GC won't delete them.
The cure for OOMEs is one or more of the following:
Find the memory leaks and fix them. There are tools to help you do this.
Modify the application to use memory more efficiently; e.g. don't keep so much data in memory, or represent it in a more compact form.
Increase the application's heap size.
1 - This is a simplification, but the full story is way to complicated for this posting. I recommend you buy an read an up-to-date book on Garbage Collection of you want (or need) a deeper understanding.
2 - There are cases involving non-heap memory where manually running the GC might help as a band-aid for certain kinds of OOME. But a better solution is to find a better way to reduce non-heap memory usage and/or free up non-heap resources in a more timely fashion.

Categories