Reputation: 1009
Somebody please clarify me the below to grasp the java memory allocation and management better. Thanks.
Q1) What is the difference between the below 3 code fragments: Why three different exist? ( In terms of when memory allocation )
Class C
{
StringBuffer sb = new StringBuffer();
C(){}
}
Class C
{
StringBuffer sb;
C()
{
sb = new StringBuffer();
}
}
Class C
{
C()
{
StringBuffer sb = new StringBuffer();
}
}
Q2) How an object created without any reference variable will be maintained. For example, new C(); new C().Hello(); How to understand their memory management, default values, scope!!
Q3) Difference between the below 2 fragments:
Class C
{
int a;
C(){}
}
Class C
{
C(){int a;}
}
Upvotes: 0
Views: 162
Reputation: 20658
An addition to the other answers:
If a new object is created, the JVM will always allocate memory in the heap of the running program and place that object there. In all your example fragments, the resulting StringBuffer
object will be placed in the heap.
Creating a new object with the new
keyword also returns a reference to that object. This reference can be assigned to a variable. And here comes the difference of your example fragments. In fragment 1 and 2 you are assigning this reference to an instance variable (aka field), which is part of an object's data - here an instance of class C
. Thus, these instance variables also reside in the heap. As long as there is also a reference to your C
instance - maybe in your main method - there will be for sure a reference to the contained StringBuffer
instance.
In fragment 3 you assign this reference to a local variable. The memory for a local variable is allocated on the stack, not on the heap. When the method ends, this memory allocation will also be discarded. There is no (local) variable anymore, that can hold a reference to an object.
An object is considered eligible for garbage collection, if there is no reference anymore to it. In your fragment 3, this will be the case for the StringBuffer
instance after the constructor ends. Note, that the Java garbage collector does not immediately run and delete all garbage. It will run at an appropriate time of the JVM's choice.
Upvotes: 0
Reputation: 27346
Fragment1
and Fragment2
are effectively the same. They both have the same scope, and create the same object. In the latter, this is done in the constructor. That is the difference. In my view, members should usually be initialised in the constructor.
Fragment3
scope is different. Once the constructor ends, C
is garbage collected. That is because, when a method is finished, all local objects are dereferenced. Once there is no reference pointing at an instance, the garbage collector does what it does best. Collects the damn garbage.
The three different examples exist because.. well.. they can be used in several different situations. You might have a member that relies on another member, so can only be initialised after the first member was.
Example
public class Test
{
private A a;
private B b;
public Test()
{
b = new B();
// As you can see, b needs to exist first.
a = new A(b);
}
How an object created without any reference variable will be maintained. For example, new C(); new C().Hello(); How to understand their memory management, default values, scope!!
If there is no reference to an object, then it will be garbage collected. When you declare new A()
it exists for as long as you use it. The second the program steps over that line of code (or collection of byte code as it were), the Garbage Collector cleans up again.
Q3) Difference between the below 2 fragments:
In the first example, a
can be used anywhere in the class. This is called a global variable
or, more specifically, an instance variable
. In the second example, you declare a local
variable. This means that it can only be used inside the method it is declared in. In this case, the constructor.
Upvotes: 1
Reputation: 43788
Q1) The fragment 1 and fragment 2 are equivalent. If the class C
had more than one constructor there would be a difference. In the fragment 1 variant you would write the initialization only once, in the fragment 2 variant you need to write it in each constructor.
In fragment 3 the variable sb
is a local variable in the constructor and only visible there. The StringBuffer
object can be garbage collected when the constructor ends.
Q2) It will not be maintained, after creation it can be garbage collected immediately. In the case of new C().Hello();
the object is only guaranteed to exist until the Hello()
method exits.
Q3) fragment 1 declares a class field, fragment 2 a local variable in the constructor.
Upvotes: 1