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.
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.
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;
I have a class defined as follows
final public class Results {
THashSet<String> filteredHashtags;
Constraints: I know that declaring a variable as static or non-static is a design problem and shouldn't be governed by memory usage but the HashSet filteredHashtags takes up significant memory (>1Gb) so I can afford slightly lower readability at the cost of lower memory usage.
Options
Non-static: As of now I've kept it non-static for the following reason: I create an instance of class, use constructor to assign value to filteredHashtags. Since I'm creating only one instance of the class, it doesn't really mater in terms of memory used by the class. When the object is no longer referred, the memory used by the variable gets freed.
Static: In terms of readability of code, I would prefer keeping it static as it relates better to the physical quantity it represents. However in this case, I need to assign value to the static variable using a function, let's say setValues(...).
Questions:
Is my assumption that in the static case, the memory associated with the variable will never be freed until the program terminates?
If yes, is there a better way to free memory other than setting filteredHashtags = null;
Rishi, your assumption that 'in the static case, the memory associated with the variable will never be freed until the program terminates' is not correct.
Static belongs to the class, and classes are loaded by loaders. Hence, memory used by static variables can be reclaimed.
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.
What is the difference between an object, instance, and reference? They say that they have to create an instance to their application? What does that mean?
An object and an instance are the same thing.
Personally I prefer to use the word "instance" when referring to a specific object of a specific type, for example "an instance of type Foo". But when talking about objects in general I would say "objects" rather than "instances".
A reference either refers to a specific object or else it can be a null reference.
They say that they have to create an instance to their application. What does it mean?
They probably mean you have to write something like this:
Foo foo = new Foo();
If you are unsure what type you should instantiate you should contact the developers of the application and ask for a more complete example.
"instance to an application" means nothing.
"object" and "instance" are the same thing. There is a "class" that defines structure, and instances of that class (obtained with new ClassName()). For example there is the class Car, and there are instance with different properties like mileage, max speed, horse-power, brand, etc.
Reference is, in the Java context, a variable* - it is something pointing to an object/instance. For example, String s = null; - s is a reference, that currently references no instance, but can reference an instance of the String class.
*Jon Skeet made a note about the difference between a variable and a reference. See his comment. It is an important distinction about how Java works when you invoke a method - pass-by-value.
The value of s is a reference. It's very important to distinguish between variables and values, and objects and references.
When you use the keyword new for example JFrame j = new JFrame(); you are creating an instance of the class JFrame.
The new operator instantiates a
class by allocating memory for a new
object and returning a reference to
that memory.
Note: The phrase "instantiating a class" means the same thing as
"creating an object." When you create
an object, you are creating an
"instance" of a class, therefore
"instantiating" a class.
Take a look here
Creating Objects
The types of the Java programming
language are divided into two
categories: primitive types and
reference types.
The reference types
are class types, interface types, and
array types.
There is also a special
null type.
An object is a
dynamically created instance of a
class type or a dynamically created
array.
The values of a reference
type are references to objects.
Refer Types, Values, and Variables for more information
I think that Object = Instance. Reference is a "link" to an Object.
Car c = new Car();
variable c stores a reference to an object of type Car.
Computer c= new Computer()
Here an object is created from the Computer class. A reference named c allows the programmer to access the object.
The main differnece is when you say ClassName obj = null; you are just creating an object for that class. It's not an instance of that class.
This statement will just allot memory for the static meber variables, not for the normal member variables.
But when you say ClassName obj = new ClassName(); you are creating an instance of the class. This staement will allot memory all member variables.
basically object and instance are the two words used interchangeably.
A class is template for an object and an object is an instance of a class.
"creating an instance of a class" how about, "you are taking a class and making a new variable of that class that WILL change depending on an input that changes"
Class in the library called Nacho
variable Libre to hold the "instance" that will change
Nacho Libre = new Nacho(Variable, Scanner Input, or whatever goes here, This is the place that accepts the changes then puts the value in "Libre" on the left side of the equals sign (you know "Nacho Libre = new Nacho(Scanner.in)" "Nacho Libre" is on the left of the = (that's not tech talk, that's my way of explaining it)
I think that is better than saying "instance of type" or "instance of class". Really the point is it just needs to be detailed out more.... "instance of type or class" is not good enough for the beginner..... wow, its like a tongue twister and your brain cannot focus on tongue twisters very well.... that "instance" word is very annoying and the mere sound of it drives me nuts.... it begs for more detail.....it begs to be broken down better. I had to google what "instance" meant just to get my bearings straight..... try saying "instance of class" to your grandma.... yikes!
The Literal meaning of instance is "an example or single occurrence of something." which is very closer to the Instance in Java terminology.
Java follows dynamic loading, which is not like C language where the all code is copied into the RAM at runtime. Lets capture this with an example.
class A
{
int x=0;
public static void main(String [] args)
{
int y=0;
y=y+1;
x=x+1;
}
}
Let us compile and run this code.
step 1: javac A.class (.class file is generated which is byte code)
step 2: java A (.class file is converted into executable code)
During the step 2,The main method and the static elements are loaded into the RAM for execution. In the above scenario, No issue until the line y=y+1. But whenever x=x+1 is executed, the run time error will be thrown as the JVM does not know what the x is which is declared outside the main method(non-static).
So If by some means the content of .class file is available in the memory for CPU to execute, there is no more issue.
This is done through creating the Object and the keyword NEW does this Job.
"The concept of reserving memory in the RAM for the contents of hard disk (here .class file) at runtime is called Instance "
Objects, which are also called instances, are self-contained elements of a program with related features and data. For the most part, you use the class merely to create instances and then work with those instances.
-Definition taken from the book "Sams Teach Yourself Java in 21 days".
Say you have 2 Classes, public class MainClass and public class Class_2 and you want to make an instance of Class_2 in MainClass.
This is a very simple and basic way to do it:
public MainClass() /*******this is the constructor of MainClass*******/
{
Class_2 nameyouwant = new Class_2();
}
I hope this helps!
Instance variable: It must be attached to the object. Instance variables in this class can only be used after instantiating the class
public class Test{
static int a = 13;
int b = 14;
public static void main(String[] args){
int d = new Test().b;
System.out.println(d);
}
}
Instance = memory is allocated at run time for anything that is called instance
Object = memory is allocated at run time for class that is called object