Stack Overflow java - java

Object as a class variable causes the stackoverflow
public class stack {
stack obj = new stack(); // its obvious that during class loading obj will call class to
// load and infinite loop will occur.
}
Lets say i am using static in from class obj
public class stack {
static stack obj = new stack(); // it will not cause infinite loop and program will //execute successfully
}
Static variables are allocated in to the memory when the class is caught by JVM first time (As far I know).
Say during first time only if the JVM starts allocating the memory to the above static object variable. It will intern call the class again and this should also cause infinite loop . Somewhere i am wrong. Can somebody highlight where i am wrong.

No, declaring it as static won't cause an infinite loop. Here is why.
Static variables are initialized during the class loading time. So when your class loads for the first time, compiler will create an instance for the static variable, and that's it. This won't cause your class to load a second time. Since your class is not loading again, this process won't be repeated.
If you declare it as a non-static attribute, then it's a totally different story. Consider this -
public class stack {
stack obj = new stack();
........
}
This declaration is equivalent to -
public class stack {
stack obj;
public stack() {
obj = new stack(); // implicitly moved here by the compiler
}
........
}
From the last example, it's pretty obvious why there is an infinite recursion here. You are creating an instance of the stack class inside its own constructor, which in turn creates another, and then another,......and it goes on, resulting in a Stack Overflow.

Loading the "stack" class will induce creating an instance of "stack", saved as static field the stack class. Then, this instance of the stack class has nothing to load: No stack exception.

keyword Static has nothing to do with infinite loop. You can declare the field, method,class(static inner class)
Static Field :- Static fields are created and initialized when the class is first loaded. That happens when a static member of the class is referred to or when an instance of the class is created, whichever comes first.
Static method:- A method declared with the static keyword. Like static fields, static methods are associated with the class itself, not with any particular object created from the class. As a result, you don’t have to create an object from a class before you can use static methods defined by the class.
The best-known static method is main, which is called by the Java runtime to start an application. The main method must be static, which means that applications run in a static context by default.
Memory Perspective:- As class is loaded once and its definition is stored in permgen area of jvm, static variables are also stored there and will lie for the life cycle of jvm.

Static variables are allocated in to the memory when the class is caught by JVM first time
Not exactly.
The static variables are allocated when the class is loaded.
The static variable initialization is performed when the class is initialized. That may happen some time after the class is loaded.
Say during first time only if the JVM starts allocating the memory to the above static object variable. It will intern call the class again and this should also cause infinite loop.
No. This is wrong for two reasons:
Objects in general are not "interned". Interning is an operation on String objects, and even then it only happens automatically for String literals. Non-literal String objects only get interned if your application calls String.intern() explicitly on them.
Even if some kind of interning was performed automatically, this would not cause an infinite loop. You seem to think that interning would somehow cause class initialization to be restarted or repeated. That cannot happen, the JVM goes to considerable lengths to ensure that each class is initialized at most once during its lifetime.

During debugging we can get to know , when first time control comes to the static variable ,
as variable is nothing but an instance of the class , it will call class loading .
then control enters in to the class , and finds a static variable object , but by this time it would be assigned by a memory address value by JVM(as done to other static variables). Control just ignores variable as instance and it assumes purely as static and program continues.

Related

Instance variable of a static nested class vs static variable of an outer class

I was using a static nested class in java for a particular use-case. A minimal example of the same is shown below:
public class Foo {
static int fooInner = getInner(); // CASE 1
private static class StaticFoo {
int fooInner = getInner(); // CASE 2
public int useFooInner(){
System.out.println(fooInner);
//do something
}
}
}
The question is how is the memory allocation in Case 1 different from that in case 2? Or is it the same?
What if I make the case 2 variable static too. Will the memory usage differ?
NOTE: Please do not mention that shadowing will take place. Although I have put both the variables there, but it's an "OR" case and that's why the "CASE"s.
PS: I feel that the memory usage should be the same. Since the nested class is static, it won't be created for every object and thus the instance variable fooInner (Case 2) will also be created just once. Thus, the getInner() function would run just once. But it is just at an abstract level + gut feeling. A more descriptive answer would be appreciated!
They are different.
From a memory allocation point of view, a static inner class is no different from a top level class. Your StaticFoo will be compiled to a class (Foo$StaticFoo.class) that is essentially independent from its parent class at runtime. At compile time, there are access checks for private members.
So, in case 1, you have a static field in a class. It will be allocated as a field on a Foo.class object on the heap. There will only be one instance per ClassLoader that loads the Foo class, which generally means just one shared instance for the whole JVM.
In case 2, you have an instance field in the Foo$StaticFoo class. On the heap, there will be space allocated (and a value assigned) for (and in) each instance of StaticFoo created. Each StaticFoo that gets created will access its own instance of that field, and since it's not final, the value of each instance can be independently changed.
If you changed StaticFoo.fooInner to be static, then it would be exactly the same as case 1.
Note: The above is true only for Java 8 and later. For earlier JVMs, that amount of memory allocated in each case still matches the description above, but static variables, as well as being singletons per ClassLoader, are also stored in a different memory pool: PermGen Space rather than the main heap. See this answer for more details.

Java instance variable of a static method

when does instance variable of a static method gets memory in java?
it is perfectly right to create instance variable in static method (either in parameter or declaring inside the function), but i want to know when does the instance variable of static method is allocated memory, if no object of the class is created?
Actually i meant to say the local variable inside static method
Firstly, the term instance variable is not accurate, I am assuming that you are asking about local variable such as a and b in the example below:
void method(int a) {
int b = 3;
}
In Java, only primitives and references are stored on stack, objects are stored in heap when they are constructed. Stack will be cleaned as soon as the scope ends, heap is cleaned by garbage collector.
Here is an example:
public class Main {
static A a = new A();
static void method() {
int b = 2;
C c = new C();
}
}
The first time your code refers to Main, class loader will load the class and initialize all its static fields - object new A() will go into heap. Nothing more happens here, method method could as well not exist.
When you call method method, it will add value 2 on the stack, then it will add reference c on the stack which will be pointing to the object new C() in the heap.
When method exists, 2 and c are removed from the stack (there is actually no removal, but the top of the stack is changed to two positions below so these two values will be overriden whenever something else comes onto stack), while new C() will remain in heap until garbage collector triggers. It's likely that it will be garbage collected immediately as GC may detect that there are no more references to this object.
If you declare a variable or use parameter inside a static method, its not at all instance variable. Its a local variable and it will be initialized once the method gets invoked
static void methodTest(int i) {
String s = "Hello";
}
Here s is a local variable to that method.
and i is the function parameter which is also a local variable to the method
There is not such thing as an instance variable in a static method.
If you mean parameters and local variables, those are allocated on stack (any created objects being allocated on heap as usual).
Static fields of the class will be initialized when the class is loaded.
Instance variables of a class will be allocated (and possibly initialized) when an instance is constructed.
The variable defined by static method is still local variable in scope of the method, just as if non-static method created local variable. However, problem is that the variable never gets garbage collected, as long as the class loader (usually main class, which gets "unloaded" only at runtime termination, which is like scratching your left ear with your right hand) is not unloaded and garbage collected. And objects get GC'd only if they are not referenced anymore, and in case of static fields, they have tendency to be referenced even when nothing uses them because of the behavior I described. So in large applications, where memory and resources are issue, it is pretty bad idea to declare anything inside static methods since you pretty soon pollute the memory with LOCAL VARIABLES that cannot be collected.

Order of initialization of data fields in java

In the code below, what is the order of initialization of data fields? What is the general rule followed by java for data member and member functions?
public class TestClass
{
int j=10;
static int h=5;
public static void main(String[] args)
{
TestClass obj= new TestClass();
}
}
In general:
1) static field members (static initializers in general)
2) non-static field members
3) constructor
However you can test it with a snippet of code like this:
public class TestClass {
int i = 10;
static int j = 20;
public TestClass() {
// TODO Auto-generated constructor stub
System.out.println(i);
i = 20;
System.out.println(i);
}
public static void main(String[] args) {
new TestClass();
}
}
Quoting from the great "Thinking In Java":
Within a class, the order of initialization is determined by the order that the variables are
defined within the class. The variable definitions may be scattered throughout and in between method definitions, but the variables are initialized before any methods can be
called—even the constructor.
...................................
There’s only a single piece of storage for a static, regardless of how many objects are created.
You can’t apply the statickeyword to local variables, so it only applies to fields. If a field is a
staticprimitive and you don’t initialize it, it gets the standard initial value for its type. If it’s
a reference to an object, the default initialization value is null.
To summarize the process of creatingan object, consider a class called Dog:
Even though it doesn't explicitly use the static keyword, the constructor is actually a
static method. So the first time an object of type Dog is created, or the first time a
static method or static field of class Dog is accessed, the Java interpreter must
locate Dog.class, which it does by searching through the class path.
As Dog.class is loaded (creating a Class object, which you’ll learn about later), all of
its static initializers are run. Thus, static initialization takes place only once, as the
Class object is loaded for the first time.
When you create a new Dog( ), the construction process for a Dog object first
allocates enough storage for a Dog object on the heap.
This storage is wiped to zero, automatically setting all the primitives in that Dog
object to their default values (zero for numbers and the equivalent for boolean and
char) and the references to null.
Any initializations that occur at the point of field definition are executed.
Constructors are executed.This might actually involve a fair amount of activity, especially when inheritance is involved.
Here is the order.
Static fields initialized and static block executed at class loading time, they will be initialized in the same order they declared.
Set fields to default initial values (0, false, null)
Call the constructor for the object (but don't execute the body of the constructor yet)
Invoke the constructor of the superclass
Initialize fields using initializers and initialization blocks
Execute the body of the constructor
I think you're just missing section 12.4.2 of JLS, which includes:
Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.
The "in textual order" part is the important bit.
If you change m from being static variable to an instance variable, then the field won't be initialized by class initialization - it'll only be initialized by instance initialization (i.e. when an instance is constructed). At the moment, that'll cause a stack overflow - creating one instance requires creating another instance, which requires creating another instance, etc.
So Finally Here is Order which you are searching for:
Initialization blocks run in the order they appear in the program.
Static initialization blocks run when the class is first loaded into JVM
Instance initialization blocks run whenever a new instance of class is created.

How many copies of a static final property are stored in memory when I have a collection of their classes

Suppose I have this simple class:
public class Car {
public static final int TYPE_SUV = 1;
public static final int TYPE_TRUCK = 2;
public String name;
public int carType;
}
Now if I have a collection of these, I know that I am allocating a String and an int for each element in the collection, but am I also storing static ints multiple times? This contrived example class is representative of the kind of Java I wrote years ago before I learned that magic numbers like this are better served with an enum which is defined in a separate class, but I've always wondered what the side effect of this code is.
From the 1.7 JLS:
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized (§12.4).
A field that is not declared static (sometimes called a non-static field) is called an instance variable. Whenever a new instance of a class is created (§12.5), a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses.
The key point to note is that memory is consumed on a per-class (not instance) basis, irrespective of how many instances you have (1, 1000 or none).
For what it's worth:
Your name and carType instance variables are only allocated when an instance is created. What's more, before java 7, Strings of an equal value could be interned - maintained in a single String instance that is referenced wherever used - into a String-managed memory (in PermGen). This changed with java 1.7 when it was moved to the main heap and seems to be changing again(?) with java 8
No copies are stored anywhere, multiple references to the same location in memory (on the heap ) are created.
static variable are related to class not with Object. So as many Object you create but static variable will be once get spaced in memory and all the Static context loads at class loading time so without creating Object also you can access your static variable with the help of class name.
No multiple copies of static is maintained. all objects have same static variables. If they have it then you have to access them using object but this is not what we do with static.
The Penalty of storing references = penalty of creating the class.

".class" way of obtaining Class - does it initialize the class?

Question is about Java. There are three ways of obtaining classes of a type (note that code is just a collection of snippets for demonstration):
Class c1 = Class.forName("com.mypkg.MyClass"); //assumes initialize = true
// - OR -
Class c1 = Class.forName("com.mypkg.MyClass", true/false,
this.getClass().getClassLoader());
Class c2 = com.mypkg.MyClass.class;
// - OR -
import com.mypkg.MyClass;
Class c2 = MyClass.class;
MyClass mc = new MyClass();
Class c3 = mc.getClass();
My question is about initialization. For method 1, I can control whether class is initialized or not using the boolean argument. For method 3, since an object is created, obviously the class is initialized (right?).
But what about method 2? Does calling .class initialize the class if it has not already been initialized?And how can one programmatically check whether a class is already initialized or not?
Summary answer:
Please see accepted solution and its comments for full answer. This is just a summary.
Calling .class does not initialize the class if it has not already been initialized. You can check whether a class is getting initialized by using a static block in the class definition that prints a message.
Reason for original question:
According to javadoc of Class.forName, "A call to forName("X") causes the class named X to be initialized.". Also there are two Class.forName methods including one that accepts a boolean parameter called initialize. According to javadoc, "The class is initialized only if the initialize parameter is true and if it has not been initialized earlier."
How about testing it yourself, to see what your VM does?
Just use this class with all three methods (in independent runs, as it will only be initialized once at most!)
class Example {
static {
System.out.println("Class was initialized!");
}
public static int bananas = 0;
}
for details when a class is supposed to be initialized, see http://docs.oracle.com/javase/specs/#12.4.1
Roughly speaking, a class is supposed to be initialized when either
the first instance is created
a static method is invoked
a non-final static field is used
some more complex corner cases
So essentially, when you first use anything of the actual class, not just reference it.
But e.g. Example.bananas = 1; should also trigger class initialization, without having an instance.
On the bytecode level, the reference to the class is loaded by the one of the ldc instructions. The VM specification does not mention that the classes are initialized, so the safe thing to say is probably that the VM does not guarantee that such a reference initializes the class, but do mind that the VM specification does not require a VM to do initialization as lazily as possible either.
The class may legally be initialized at any time between it being first referenced and initialization being strictly required.

Categories