I want to know what all variables are garbage collected in my program and the order of garbage collection. Is there a simple way to do that:
class GarbageUtility {
public static void main(String args[]) {
int a =10;
int b = a;
int c = a + b;
System.out.println(a);
}
}
you may have a look at com.sun.management.GarbageCollectionNotificationInfo, see http://docs.oracle.com/javase/7/docs/jre/api/management/extension/com/sun/management/GarbageCollectionNotificationInfo.html
also, this post presents a way to make a gc detector for hashmaps, http://java.dzone.com/articles/letting-garbage-collector-do-c
I want to know what all variables are garbage collected in my program and the order of garbage collection. Is there a simple way to do that:
No there isn't1.
Variables are not garbage collected2. Objects are garbage collected ... or at least, they may be garbage collected.
Most of the variables in you program have type int and int is not an object / reference type. They won't even be affected by the garbage collector.
Your program won't even compile ...
Footnotes:
There are a couple of ways that you can use to infer that an object is being garbage collected:
If you declare a finalize() method, that will be called when the GC detects that the object has no strong, soft or weak references to is ... and garbage collection is imminent. You can get a similar effect with Reference objects and their associated queues. Note however that this may also change the lifetime of the respective objects ... causing them to live longer than they otherwise might.
You might be able to detect that an object is dues to be garbage collected via the external debugger or profiler agents. (I'm not sure about this. I actually think that unreachable objects are invisible to the agents.)
Actually, it is a little more complicated than that.
Variables don't have an independent lifetime. They are always part of "something else" ... and the "something else" can be garbage collected ... in some cases:
We can divide variables into 3 kinds:
Stack variables (that is method parameters and locals) are not stored in space that is managed by the GC. Any object whose reference is in a (live) stack variable won't be garbage collected.
Instance variables (instance fields declared by a class) are part of the respective object. When the object is garbage collected, the variables "go away".
Static variables (static fields declared by a class) normally stay around for the lifetime of the application. However, there are circumstances where a class may be garbage collected, and if that happens its static variables go away at the same time.
Note that GarbageCollectionNotificationInfo tells you that the GC has collected a certain heap, and gives some basic statistics such as how long the GC took and what space was available in the heap before and after.
I don't see how that helps you tell whether specific objects have been garbage collected and when it happened.
Related
As Java does has an automatic garbage collector, it does not have a destructor. How will I come to know that an object has garbage so to decrement the static variable count?
Objects have finalize() method which is called by the garbage collector when it determines that there are no more references to the object.
See here
I was reading about garbage collection and finalization in Java and when I tried an example. I click button 1, and memory jumps up. But when I click button 2, the memory didn't free up used space!
What did I do wrong and how do I free memory from unused objects?
As far as I know (I may be wrong):
When the same variable is re-instantiated again and again, the old object shall be destroyed.
When I set a variable to null the the old object shall be destroyed.
Array cells are null values. They shall be destroyed when parent array object has no variable to reference it.
How do I free up collections? How do array rules apply?
Code:
public class Memory extends javax.swing.JFrame {
Object[] object;
private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {
object = new Object[10240000];
}
private void Button2ActionPerformed(java.awt.event.ActionEvent evt) {
object = null;
System.gc();
System.runFinalization();
//OR
System.runFinalization();
System.gc();
}
}
The System.gc() is only a suggestion for the JVM to clean up the memory. It may or may not take this suggestion. You are not doing anything wrong. Relax.
Java will clean unused objects out eventually, that's what garbage collector is for. You don't have to worry about it or write any code for it.
GC in Java periodically and it is not instantaneous, System.gc() only suggests that GC should run, which might not happen.
If you want to see java GC in action you should try a program with longer run-time to see what's going on with memory and GC in action.
When same variable is re-initanciated more and more the old object shall be destroyed.
When set a variable to null the the old object shall be destroyed
Array cells are null values they shall be destroyed when parent array object has no variable to reference it
How to free up collections or Array rules apply?
Answer to all four points is: Garbage collector will take care of that.
Also the reason why memory is high even though the garbage collector probably did run is that JVM takes more memory than just the objects.
I am reading about memory management in JVM and that if an object has no more references to it, it is garbage collected.
lets say, I have a program
public test {
public static void main(String[ ] args) {
String name = "hello";
for (int i =0 ; i < 5; i++) {
System.out.println(i);
}
}
}
As you can see, the String name is not used anywhere, so its reference is kept through out and not garbage collected.
now I have,
String name = "hello"
String name2 = name.substring(1,4)//"ell"
here again, the reference for hello must be present always, and cannot be garbage collected, since name2 uses it.
so when do these String or any objects get garbage collected, which have references but are obsolete, i.e. no longer used in code?
I can see one scenario where trimming down an array causes memory leak and hence setting its reference to null is a good way to garbage collect those obsolete references.
I can see one scenario where trimming down an array causes memory leak
and hence setting its reference to null is a good way to garbage
collect those obsolete references.
Strings are reference types, so all the rules for reference types with respect to garbage collection apply to strings. The JVM may also do some optimizations on String literals but if you're worrying about these, then you're probably thinking too hard.
When does the JVM collect unreferenced objects?
The only answer that matters is: you can't tell and it needn't ever, but if it does you can't know when that will be. You should never write Java code around deterministic garbage collection. It is unnecessary and fraught with ugliness.
Speaking generally, if you confine your reference variables (including arrays or collections of reference types) to the narrowest possible scope, then you'll already have gone a long way toward not having to worry about memory leaks. Long-lived reference types will require some care and feeding.
"Trimming" arrays (unreferencing array elements by assigning null to them) is ONLY necessary in the special case where the array represents your own system for managing memory, eg. if you are making your own cache or queue of objects.
Because the JVM can't know that your array is "managing memory" it can't collect unused objects in it that are still referenced but are expired. In cases where an array represents your own system for managing memory, then you should assign null to array elements whose objects have expired (eg. popped off a queue; J. Bloch, Essential Java, 2nd Ed.).
Technically, the JVM is not required to garbage-collect objects ever. In practice, they usually come behind a little while after the last reference is gone and free up the memory.
First, be aware that constants are always going to be around. Even if you assign a new value to name, the system still has a copy of "hello" stored with the class that it will reuse every time you hit that initializer statement.
However, don't confuse using an object for some sort of calculation with keeping a reference to it forever. In your second example, while "hello" is in fact kept around, that's just because it's living in the constant pool; name2 doesn't have any sort of "hold" on it that keeps it in memory. The call to substring executes and finishes, and there's no eternal hold on name. (The actual implementation in the Oracle JVM shares the underlying char[], but that's implementation-dependent.)
Clearing out arrays is a good practice because it's common for them to be long-lived and reused. If the entire array gets garbage collected, the references it holds get erased (and their objects garbage collected if those were the last ones).
Every variable in Java has a scope: The piece of code during which the variable is defined. The scope of a local variable like name in your example is between the brackets {} it is in. Thus, the name variable will be defined when the thread reaches the String name = "hello"; declaration, and will be kept alive until the main method is finished (because then the brackets the variable was in are closed).
Strings are a different story though than other variables. Strings are cached internally and may not actually be made available for the garbage collector yet.
If I have a class Sample and I have an instance method, instanceMethod in it.
The class has a main method where I create an object of Sample itself and call it's instanceMethod without using a reference variable.
like this:
new Sample().instanceMethod();
inside the main.
Since this object has NO reference, will the garbage collector collect it ?
In Java1, I don't believe the object can be collected while instanceMethod() is being executed. In the main method's stack frame there is a reference to the object, at least logically (the JIT compiler may elide it). The fact that you're not assigning it to a variable doesn't affect the bytecode very much.
Of course when instanceMethod() completes, the object may be eligible for garbage collection - but it may not. For example, instanceMethod() may store a reference to this in a static variable.
Basically it's not worth getting hung up over intricate corner cases - just rely on the GC collecting objects which can't be reached any more in any way, but not collecting objects which may still be in use.
1 In .NET an object can still be garbage collected while an instance method is executing "in" the object, if the JIT compiler can prove that none of its variables will be read again. It's very confusing, and can cause very subtle bugs.
If my application has too many static variables or methods, then as per definition they will be stored in heap. Please correct me if I am wrong
1) Will these variables be on heap until application is closed?
2) Will they be available for GC at any time? If not can I say it is a memory leak?
Static methods are just methods, they are not stored on the heap, they just don't get to use a "this" parameter.
Static variables serve as "roots" to the GC. As a result, unless you explicitly set them to null, they will live as long as the program lives, and so is everything reachable from them.
A situation is only considered a memory leak if you intend for the memory to become free and it doesn't become free. If you intend for your static variable to contain a reference to an object for part of the time, and you forget to set it to null when you're done with that object, you would likely end up with a leak. However, if you put it in the static variable and intend for it to be there for as long as the program is running, then it is most definitely not a leak, it is more likely a "permanent singleton". If the object got reclaimed while you wanted it to still exist, that would have been very bad.
As for your question about the heap: All objects in Java exist either on the heap or on the stack. Objects are created on the heap with the new operator. A reference is then attached to them. If the reference becomes null or falls out of scope (e.g., end of block), the GC realizes that there is no way to reach that object ever again and reclaims it. If your reference is in a static variable, it never falls out of scope but you can still set it to null or to another object.
If you have a static hashmap and you add data to it... the data will never disappear and you have a leak - in case you do not need the data anymore. If you need the data, it is not a leak, but a huge pile of memory hanging around.
Objects directly or indirectly referenced by statics will remain on the heap until the appropriate class loader can be collected. There are cases (ThreadLocal, for instance) where other objects indirectly reference the class loader causing it to remain uncollected.
If you have a static List, say, and add references to it dynamically, then you can very easily end up with "object lifetime contention issues". Avoid mutable statics for many reasons.
As long as you can reference these variables from somewhere in the code it can't by GCed which means that they will be there until the end of the application.
Can you call it a memory leak, I wouldn't call it a memory leak, usually a memory leak is memory that you normally expect to recover but you never do, or you only recover part of it. Also memory leaks usually get worse in time (eg: every time you call a method more memory is "leaked") however in this case the memory usage for those variables is (kind of) static.
It won't cause a memory leak in the classic C sense... For example
Class A{
static B foo;
...
static void makeFoo(){
foo = new B();
foo = new B();
}
In this case, a call to makeFoo() won't result in a memory leak, as the first instance can be garbage collected.