class A // Normal Class
{
static int i; // Static int variable
int j; // Normal int variable
}
Suppose I create two objects namely A1, A2.
Do both objects have separate memory allocated for the variable i or the common, Permgen space
What would be the size of A1, A2? If suppose the size of int is assumed as 2 bytes.
Same memory, static member variables are shared between instances because static is class level and they are both of the same class.
As for the size of the objects, they would the the size of the object minus the static member variables.
Also
static has a lowercase 's', not uppercase. Keywords are case sensitive.
int is 4 bytes, not 2
Does both the objects have seperate memory allocated for the variable i?.
Static members are at class (and not instance) level. So, there will be only one int i. j is at instance level, so each instance of A will have a j in it.
So, your question is kind of invalid. Why?
because static has no relation with instance of class (Like Marko Toplonik says)
instanceOfA.i will actually be resolved to A.i
What would be the size of each instance
The size of the object depends on instance members only.
How to prove it?
Calculate the size of object of type A and check what is prints and then do the same without static variable in class A?
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new A());
System.out.println(baos.size());
Static instance are declared in the inside of the class template. Compiler is load the class to the memory only one time, and using this template compiler is creating byte code. JVM is creating object by using this class template and do not load more and more same class template to create more and more objects. Therefore static instance are declared only one time. Every object of the same class are access the same static instance.
Good Luck !!!
Static variables are loaded at time when the class is loaded, so they are allocated a constant memory space irrespective of number of objects created.
So, the memory for the variable i remains same for all the objects created.
You can even access the static variables and functions without creating the objects, just by using the class name.
class A
{
static int i;
}
A.i=10;
Related
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.
This question already has answers here:
What occurs when object is created in Java?
(5 answers)
Order of initialization of data fields in java
(3 answers)
Closed 3 years ago.
When a global variable is declared and initialized with a value, then while creating object of the class, is the global variable again gets initialized and gets a new memory?
class A{
int a = 10;
}
This will gets stored in the memory address a with value 10. But when I create object of the class A, then is the a gets initialized again?
class A{
int a = 10;
public static void main(String args[]){
A a = new A();
}
what you said is not quite how memory allocation works.
class A{
int a = 10;
}
in the above example you created a class. the members in the class are only created and assigned their values after their objects are created unless the the members are declared as static. hence the variable 'a' is assigned the value 10 after the construction of the object 'a' of class A in the second example you posted. If you still don't understand, then run this code:
class A{
int a = 10;
public static void main(String args[]){
A a = new A();
A b = new A();
b.a += 10;
System.out.println(a.a);
System.out.println(b.a);
}
}
if the variable a was assigned before creation of object, then when object b modifies it, the variable printed would change. But if you run this the out put will be:
10
20
which means that the variables only got assigned after object creation. I hope this clears your doubt. Also another tip for you, Static variables cannot be modified.
When a global variable is declared and initialized with a value...
What you have shown is not a global variable. Truly global variables do not exist in Java. a is an instance field of A.
This will gets stored in the memory address a with value 10.
a is not a memory address, it is just the name of the field. You rarely need to deal with low-level stuff such as memory addresses in Java.
But when I create object of the class A, then is the a gets initialized again?
Before you create an instance, no memory is allocated for the a field, except maybe for storing the compiled class file itself. It is once you create an instance of A that there is a place in memory storing the value 10 that corresponds to the a field of that instance.
Note that if you create a second instance of A, another piece of memory will be allocated to hold the a of that instance.
There is no global variables in Java. There are class and object variables. Class variables are defined by the static keyword.
In your code, the a variable is an object variable, it is created (and initialized) every time a new object of the class is created, in this case, with the call new A().
If you created another object of the class A, another object variable awould be created (and initialized) for it, different that the first one.
Why static variable value been allowed to print directly in main method, while to print normal integer type value, it requires to creation of object.
although that is global, but x is also being accessed in same class then why i can't directly access that.
While answering, please cover memory allocation part.
From my understanding
static, as it is global variable stored on permanent generation, then what about this primitive int x, is this not allocated on private stack? Please assist.
public class Test{
int x = 7;
static int y = 10;
public static void main(String[] args) {
System.out.println("the value of y "+ y);
//compile error on sysout for value x like this,
//System.out.println("the value of x "+ x);
//While in this way i am able to print x, why?
Test test= new Test();
System.out.println("the value of x "+test.x);
}
}
Please assist on memory allocation of program, Thanks in advance!
The static modifier on a field means that that field is shared by the entire class, not just specific instances. Without static, the field is part of instances of the class (created with new).
Your main method, also static, is run without any insance of the class. So it has access to class fields (aka "class variables") declared with static, but since it doesn't have an instance, it can't access instance fields (aka "instance variables").
Test test = new Test(); creates an instance, which you're referencing from the test variable. That instance has a field, x, and so you can access it.
In terms of memory allocation:
Memory for the class and various other classes will be allocated by the JVM when starting up your program so it can call main (allocating memory for the Test class includes a small bit for y).
Within main, you're allocating memory for an instance of Test via new Test (which includes a small bit of memory for x).
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.
I'm reading a book "Thinking in Java" which says
objects are stored on heap and static variable on stored on some fixed location say static storage so that they can be available for entire time program is running.
class Myclass{
static int x =0; //stored on static storage
Myclass obj = new Myclass(); //stored on heap
}
Although making a object, static will not be a good idea as far as OOPS is concerned. Putting this aside for a while. there comes my questions that
where does object which is declared static is stored.
how does JVM does instantiation in this case.
class Myclass { static Myclass obj = new Myclass(); //no man's land }
All static content will be created on class load/initiation and stored in special location (most probably part of perm gen, differs based on implementation).
For second example, When your Myclass is loaded, it's static content will be created/instantiated.
This tutorial may give you high level overview.
Static is a special memory location to the program. So the program could easily access it. Only one such location available for the program to run. And it's the place where static content is created. The JVM instantiates objects on the heap. But if you make a static reference to the object then it placed in the static memory place.
static variables are stored on method area.
method area is part of non-heap memory. It stores per-class structures, code for methods and constructors. Per-class structure means runtime constants and static fields.
It depends on JVM implementation. In your example the variable is initialized to a primitive value and so it will be stored in metaspace(native memory, offheap). In case you initialized it with new ObjectClassSmthng() the object will be stored on heap and x variable (which is a reference) would be stored in metaspace.
This is true for HotSpot JDK 8.