For example:
class A {
static int i=0;
static int j;
static void method() {
// static k=0; can't use static for local variables only final is permitted
// static int L;
}
}
Where will these variables be stored in Java, in heap or in stack memory? How are they stored?
Static methods (in fact all methods) as well as static variables are stored in the PermGen section of the heap, since they are part of the reflection data (class related data, not instance related). As of Java 8 PermGen has been replaced by MetaSpace and as per JEP 122 it only holds meta-data while static fields are stored in the heap.
Note that this mostly applies to Oracle's Hotspot JVM and others that are based on it. However, not every JVM has PermGen or Metaspace like Eclipse OpenJ9.
Update for clarification:
Note that only the variables and their technical values (primitives or references) are stored in PermGen space.
If your static variable is a reference to an object that object itself is stored in the normal sections of the heap (young/old generation or survivor space). Those objects (unless they are internal objects like classes etc.) are not stored in PermGen space.
Example:
static int i = 1; //the value 1 is stored in the PermGen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the PermGen section, the object itself is not.
A word on garbage collection:
Do not rely on finalize() as it's not guaranteed to run. It is totally up to the JVM to decide when to run the garbage collector and what to collect, even if an object is eligible for garbage collection.
Of course you can set a static variable to null and thus remove the reference to the object on the heap but that doesn't mean the garbage collector will collect it (even if there are no more references).
Additionally finalize() is run only once, so you have to make sure it doesn't throw exceptions or otherwise prevent the object to be collected. If you halt finalization through some exception, finalize() won't be invoked on the same object a second time.
A final note: how code, runtime data etc. are stored depends on the JVM which is used, i.e. HotSpot might do it differently than JRockit and this might even differ between versions of the same JVM. The above is based on HotSpot for Java 5 and 6 (those are basically the same) since at the time of answering I'd say that most people used those JVMs. Due to major changes in the memory model as of Java 8, the statements above might not be true for Java 8 HotSpot - and I didn't check the changes of Java 7 HotSpot, so I guess the above is still true for that version, but I'm not sure here.
Prior to Java 8:
The static variables were stored in the permgen space(also called the method area).
PermGen Space is also known as Method Area
PermGen Space used to store 3 things
Class level data (meta-data)
interned strings
static variables
From Java 8 onwards
The static variables are stored in the Heap itself.From Java 8 onwards the PermGen Space have been removed and new space named as MetaSpace is introduced which is not the part of Heap any more unlike the previous Permgen Space. Meta-Space is present on the native memory (memory provided by the OS to a particular Application for its own usage) and it now only stores the class meta-data.
The interned strings and static variables are moved into the heap itself.
For official information refer : JEP 122:Remove the Permanent Gen Space
Class variables(Static variables) are stored as part of the Class object associated with that class. This Class object can only be created by JVM and is stored in permanent generation.
Also some have answered that it is stored in non heap area which is called Method Area. Even this answer is not wrong. It is just a debatable topic whether Permgen Area is a part of heap or not. Obviously perceptions differ from person to person. In my opinion we provide heap space and permgen space differently in JVM arguments. So it is a good assumption to treat them differently.
Another way to see it
Memory pools are created by JVM memory managers during runtime. Memory pool may belong to either heap or non-heap memory.A run time constant pool is a per-class or per-interface run time representation of the constant_pool table in a class file. Each runtime constant pool is allocated from the Java virtual machine’s method area and Static Variables are stored in this Method Area.
Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.(Reference)
This is a question with a simple answer and a long-winded answer.
The simple answer is the heap. Classes and all of the data applying to classes (not instance data) is stored in the Permanent Generation section of the heap.
The long answer is already on stack overflow:
There is a thorough description of memory and garbage collection in the JVM as well as an answer that talks more concisely about it.
It is stored in the heap referenced by the class definition. If you think about it, it has nothing to do with stack because there is no scope.
In addition to the Thomas's answer , static variable are stored in non heap area which is called Method Area.
As static variables are class level variables, they will store " permanent generation " of heap memory.
Please look into this for more details of JVM. Hoping this will be helpful
static variables are stored in the heap
When we create a static variable or method it is stored in the special area on heap: PermGen(Permanent Generation), where it lays down with all the data applying to classes(non-instance data). Starting from Java 8 the PermGen became - Metaspace. The difference is that Metaspace is auto-growing space, while PermGen has a fixed Max size, and this space is shared among all of the instances. Plus the Metaspace is a part of a Native Memory and not JVM Memory.
You can look into this for more details.
In real world or project we have requirement in advance and needs to create variable and methods inside the class , On the basis of requirement we needs to decide whether we needs to create
Local ( create n access within block or method constructor)
Static,
Instance Variable( every object has its own copy of it),
=>2. Static Keyword will be used with variable which will going to be same for particular class throughout for all objects,
e.g in selenium : we decalre webDriver as static => so we do not need to create webdriver again and again for every test case
Static Webdriver driver
(but parallel execution it will cause problem, but thats another case);
Real world scenario => If India is class, then flag, money would be same for every Indian, so we might take them as static.
Another example: utility method we always declare as static b'cos it will be used in different test cases.
Static stored in CMA( PreGen space)=PreGen (Fixed memory)changed to Metaspace after Java8 as now its growing dynamically
As of Java 8 , PermGen space is Obsolete. Static Methods,Primitives and Reference Variables are stored in Java MetaSpace. The actual objects reside in the JAVA heap. Since static methods never get out of reference they are never Garbage collected both from MetaSpace and the HEAP.
Related
I know the concept of a constants pool and the String constant pool used by JVMs to handle String literals. But I don't know which type of memory is used by the JVM to store String constant literals. The stack or the heap? Since its a literal which is not associated with any instance I would assume that it will be stored in stack. But if it's not referred by any instance the literal has to be collected by GC run (correct me if I am wrong), so how is that handled if it is stored in the stack?
The answer is technically neither. According to the Java Virtual Machine Specification, the area for storing string literals is in the runtime constant pool. The runtime constant pool memory area is allocated on a per-class or per-interface basis, so it's not tied to any object instances at all. The runtime constant pool is a subset of the method area which "stores per-class structures such as the runtime constant pool, field and method data, and the code for methods and constructors, including the special methods used in class and instance initialization and interface type initialization". The VM spec says that although the method area is logically part of the heap, it doesn't dictate that memory allocated in the method area be subject to garbage collection or other behaviors that would be associated with normal data structures allocated to the heap.
As explained by this answer, the exact location of the string pool is not specified and can vary from one JVM implementation to another.
It is interesting to note that until Java 7, the pool was in the permgen space of the heap on hotspot JVM but it has been moved to the main part of the heap since Java 7:
Area: HotSpot
Synopsis: In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.
RFE: 6962931
And in Java 8 Hotspot, Permanent Generation has been completely removed.
String literals are not stored on the stack. Never. In fact, no objects are stored on the stack.
String literals (or more accurately, the String objects that represent them) are were historically stored in a Heap called the "permgen" heap. (Permgen is short for permanent generation.)
Under normal circumstances, String literals and much of the other stuff in the permgen heap are "permanently" reachable, and are not garbage collected. (For instance, String literals are always reachable from the code objects that use them.) However, you can configure a JVM to attempt to find and collect dynamically loaded classes that are no longer needed, and this may cause String literals to be garbage collected.
CLARIFICATION #1 - I'm not saying that Permgen doesn't get GC'ed. It does, typically when the JVM decides to run a Full GC. My point is that String literals will be reachable as long as the code that uses them is reachable, and the code will be reachable as long as the code's classloader is reachable, and for the default classloaders, that means "for ever".
CLARIFICATION #2 - In fact, Java 7 and later uses the regular heap to hold the string pool. Thus, String objects that represent String literals and intern'd strings are actually in the regular heap. (See #assylias's Answer for details.)
But I am still trying to find out thin line between storage of string literal and string created with new.
There is no "thin line". It is really very simple:
String objects that represent / correspond to string literals are held in the string pool.
String objects that were created by a String::intern call are held in the string pool.
All other String objects are NOT held in the string pool.
Then there is the separate question of where the string pool is "stored". Prior to Java 7 it was the permgen heap. From Java 7 onwards it is the main heap.
String pooling
String pooling (sometimes also called as string canonicalisation) is a
process of replacing several String objects with equal value but
different identity with a single shared String object. You can achieve
this goal by keeping your own Map (with possibly soft
or weak references depending on your requirements) and using map
values as canonicalised values. Or you can use String.intern() method
which is provided to you by JDK.
At times of Java 6 using String.intern() was forbidden by many
standards due to a high possibility to get an OutOfMemoryException if
pooling went out of control. Oracle Java 7 implementation of string
pooling was changed considerably. You can look for details in
http://bugs.sun.com/view_bug.do?bug_id=6962931 and
http://bugs.sun.com/view_bug.do?bug_id=6962930.
String.intern() in Java 6
In those good old days all interned strings were stored in the PermGen
– the fixed size part of heap mainly used for storing loaded classes
and string pool. Besides explicitly interned strings, PermGen string
pool also contained all literal strings earlier used in your program
(the important word here is used – if a class or method was never
loaded/called, any constants defined in it will not be loaded).
The biggest issue with such string pool in Java 6 was its location –
the PermGen. PermGen has a fixed size and can not be expanded at
runtime. You can set it using -XX:MaxPermSize=96m option. As far as I
know, the default PermGen size varies between 32M and 96M depending on
the platform. You can increase its size, but its size will still be
fixed. Such limitation required very careful usage of String.intern –
you’d better not intern any uncontrolled user input using this method.
That’s why string pooling at times of Java 6 was mostly implemented in
the manually managed maps.
String.intern() in Java 7
Oracle engineers made an extremely important change to the string
pooling logic in Java 7 – the string pool was relocated to the heap.
It means that you are no longer limited by a separate fixed size
memory area. All strings are now located in the heap, as most of other
ordinary objects, which allows you to manage only the heap size while
tuning your application. Technically, this alone could be a sufficient
reason to reconsider using String.intern() in your Java 7 programs.
But there are other reasons.
String pool values are garbage collected
Yes, all strings in the JVM string pool are eligible for garbage
collection if there are no references to them from your program roots.
It applies to all discussed versions of Java. It means that if your
interned string went out of scope and there are no other references to
it – it will be garbage collected from the JVM string pool.
Being eligible for garbage collection and residing in the heap, a JVM
string pool seems to be a right place for all your strings, isn’t it?
In theory it is true – non-used strings will be garbage collected from
the pool, used strings will allow you to save memory in case then you
get an equal string from the input. Seems to be a perfect memory
saving strategy? Nearly so. You must know how the string pool is
implemented before making any decisions.
source.
As other answers explain Memory in Java is divided into two portions
1. Stack: One stack is created per thread and it stores stack frames which again stores local variables and if a variable is a reference type then that variable refers to a memory location in heap for the actual object.
2. Heap: All kinds of objects will be created in heap only.
Heap memory is again divided into 3 portions
1. Young Generation: Stores objects which have a short life, Young Generation itself can be divided into two categories Eden Space and Survivor Space.
2. Old Generation: Store objects which have survived many garbage collection cycles and still being referenced.
3. Permanent Generation: Stores metadata about the program e.g. runtime constant pool.
String constant pool belongs to the permanent generation area of Heap memory.
We can see the runtime constant pool for our code in the bytecode by using javap -verbose class_name which will show us method references (#Methodref), Class objects ( #Class ), string literals ( #String )
You can read more about it on my article How Does JVM Handle Method Overloading and Overriding Internally.
To the great answers that already included here I want to add something that missing in my perspective - an illustration.
As you already JVM divides the allocated memory to a Java program into two parts. one is stack and another one is heap. Stack is used for execution purpose and heap is used for storage purpose. In that heap memory, JVM allocates some memory specially meant for string literals. This part of the heap memory is called string constants pool.
So for example, if you init the following objects:
String s1 = "abc";
String s2 = "123";
String obj1 = new String("abc");
String obj2 = new String("def");
String obj3 = new String("456);
String literals s1 and s2 will go to string constant pool, objects obj1, obj2, obj3 to the heap. All of them, will be referenced from the Stack.
Also, please note that "abc" will appear in heap and in string constant pool. Why is String s1 = "abc" and String obj1 = new String("abc") will be created this way? It's because String obj1 = new String("abc") explicitly creates a new and referentially distinct instance of a String object and String s1 = "abc" may reuse an instance from the string constant pool if one is available. For a more elaborate explanation: https://stackoverflow.com/a/3298542/2811258
I know JVM uses stack and heap for allocation of memory for object reference, object value and memory for methods. But I am confused about the terminologies: METHOD AREA, HEAP and JAVA STACK and I have few question's.
When we say "ClassName obj = new ClassName()", new creates an object on the HEAP(the instance variables and static variables too) and what is returned to the reference(obj)? Some people use to say it is CLASS TYPE, does it mean the hash code?
When new creates the object on the heap, at the same time: i)the methods,corresponding to that object ii)local variables and iii)the reference to that object are stored as part of STACK( is it JAVA STACK?). If so, then what does METHOD AREA do? Or am I wrong?
What is the amount of memory allocated for that object?
i. for object reference
ii. for object values(it depends on the local variables)
iii. will there be a memory allocated to point the object's methods?( because the non-static members are not shared among the objects and a separate copy is maintained for each objects including the methods).
By the way, where does static methods are stored?
When we say "ClassName obj = new ClassName()", new creates an object
on the HEAP(the instance variables and static variables too) and what
is returned to the reference(obj)? Some people use to say it is CLASS
TYPE, does it mean the hash code?
Yes new creates Object on the HEAP. Heap is a memory place where the objects and its instance variable are stored. Not static variables since static variables doesn't belong to Object it belongs to class so are stored on PermGem Sections (class related data, not instance related).
What is Returned : the reference(pointer/memory address) i.e hashcode
When new creates the object on the heap, at the same time: i)the
methods,corresponding to that object ii)local variables and iii)the
reference to that object are stored as part of STACK( is it JAVA
STACK?). If so, then what does METHOD AREA do? Or am I wrong?
since All threads share the same method area methods don't corresponds to Objects it belongs to class
what does METHOD AREA do :The method area stores per-class information, like Run Time Constant Pool, Method code, The method's return type (or void) etc
What is the amount of memory allocated for that object? i. for object
reference ii. for object values(it depends on the local variables)
iii. will there be a memory allocated to point the object's methods?(
because the non-static members are not shared among the objects and a
separate copy is maintained for each objects including the methods).
Amount of Memory for Object Reference: it depends as on many VMs the size of a reference is the native pointer size and for (iii) above point already cleared that
I know JVM uses stack and heap for allocation of memory for object reference
correct.
object value
I assume you means the object's header and fields.
and memory for methods.
Methods are not stored in the heap, or stack. When you profiler the heap usage or set the maximum heap size, the use of methods makes no difference as they are not on the heap in the Oracle or OpenJDK JVM.
They are stored in the PermGen or MetaSpace or some other space depending on which JVM you are using.
But I am confused about the terminologies: METHOD AREA,
From Method Area in Java
The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads. The method area is analogous to the storage area for compiled code of a conventional language or analogous to the "text" segment in an operating system process. It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization.
HEAP
Shared space for storing objects. This is usually one continuous region of native memory managed by the JVM.
and JAVA STACK
The thread's stack which is actually a native thread stack on most JVM.
When we say "ClassName obj = new ClassName()", new creates an object on the HEAP(the instance variables and static variables too)
It might, but it can also eliminate the object with escape analysis, placing the fields on the stack, and possibly eliminating those.
and what is returned to the reference(obj)?
Correct, Java only has references and primitives (if you ignore the void type which is neither)
Some people use to say it is CLASS TYPE,
The reference is defined by giving the type of the reference which is a class or interface.
does it mean the hash code?
A hash code is a hash value for the object. It is not releated to anything else you have mentioned.
When new creates the object on the heap,
When you create a new object on the heap, you just create space for the header of the object (which points to the class and it's methods) and space for it's fields. (Those the JVM doesn't optimise away)
at the same time: i)the methods
The methods are loaded/compiled in various stages. The methods are loaded as they are needed for the first time and later if they are compiled.
corresponding to that object ii)local variables
Local variables are on the stack, not on the heap, not in the object.
iii)the reference to that object are stored as part of STACK( is it JAVA STACK?).
The Java Stack, is the Stack, is the native stack.
If so, then what does METHOD AREA do?
Store the code for the methods.
What is the amount of memory allocated for that object?
About 8-12 bytes per header, space for each primitive field and reference and alignment padding of 8 or 16 bytes (32 GB - 64 GB heaps).
i. for object reference
Typically this is 32-bit on 64-bit JVMs (With compressed oops). If you have more than 64 GB heap it will be 64 -bit.
ii. for object values(it depends on the local variables)
Local variables are on the heap not the object.
iii. will there be a memory allocated to point the object's methods?
Method memory usage is not visible to you. It is not on the heap, nor something you can measure on a per method basis. I don't know of a profiler which will even show you this.
( because the non-static members are not shared among the objects and a separate copy is maintained for each objects including the methods).
That sounds like an insane waste of space, and it is, which is why the JVM does do that. There is only one copy for a method, regardless of the number of instances.
By the way, where does static methods are stored?
With all the other methods. There is no difference between a static method and a non-static method except a non-static method must take an instance as it's first argument at the JVM level. (And there is a bit in the modifiers to say whether it is static or not)
Let's say I have this code:
{
int var = 2;
// more code
}
What happens with 'var' after the code is executed and it is not used anymore? Is it deleted from memory or it stays there occupying memory, or something else?
Related to this, is it better to work with variables that way^, or to make some global variable and just change it's value?
Local variables live on the stack. If it's a reference to an object then only variable is on the stack.
Instance variables live on the heap because they belong to an object.
Also this post (Stack and heap memory in java) might be helpful.
To make a long story short, in java (and other JVM languages), you don't have to care about memory allocation and dealocation at all. You really shouldn't be worrying about it. Once you lose the reference to that variable (in this case, when the method call ends), the variable is effectively gone. Some indefinite amount of time after that, the Garbage collecting thread will notice that you can't possibly access that variable anymore, and free up the memory it was using.
See: Garbage Collection in Java.
if you are defining any variable as instance variable then that variable will be used by instance. and instance will be saved in Heap memory area.
Garbage collector will run periodically to clean non referenced object from memory.
but if that variable is defined inside any block or method then that will be stored Stack memory.
Java Stack memory is used for execution of a thread. They contain method specific values that are short-lived and references to other objects in the heap that are getting referred from the method. Stack memory is always referenced in LIFO (Last-In-First-Out) order. Whenever a method is invoked, a new block is created in the stack memory for the method to hold local primitive values and reference to other objects in the method. As soon as method ends, the block becomes unused and become available for next method.
Everything in Java is removed from memory when it is no longer referenced. It takes a lot of effort to cause true memory leaks in Java.
Java primitives like int, boolean, and char are put on the stack and removed from memory as soon as they leave scope. Java objects like String, arrays, or ArrayList are allocated on the heap (and referenced by the local variable on the stack). Objects are garbage collected (removed from memory) when there is no longer a reference to them.Static variables belong to a class and will be a reference an object as long as the class is loaded, which is usually the entire run time of the Java program. Statics are the closest thing Java has to global variables, but overuse or misuse of statics is actually a way to cause memory issues rather than solve them.
I know the concept of a constants pool and the String constant pool used by JVMs to handle String literals. But I don't know which type of memory is used by the JVM to store String constant literals. The stack or the heap? Since its a literal which is not associated with any instance I would assume that it will be stored in stack. But if it's not referred by any instance the literal has to be collected by GC run (correct me if I am wrong), so how is that handled if it is stored in the stack?
The answer is technically neither. According to the Java Virtual Machine Specification, the area for storing string literals is in the runtime constant pool. The runtime constant pool memory area is allocated on a per-class or per-interface basis, so it's not tied to any object instances at all. The runtime constant pool is a subset of the method area which "stores per-class structures such as the runtime constant pool, field and method data, and the code for methods and constructors, including the special methods used in class and instance initialization and interface type initialization". The VM spec says that although the method area is logically part of the heap, it doesn't dictate that memory allocated in the method area be subject to garbage collection or other behaviors that would be associated with normal data structures allocated to the heap.
As explained by this answer, the exact location of the string pool is not specified and can vary from one JVM implementation to another.
It is interesting to note that until Java 7, the pool was in the permgen space of the heap on hotspot JVM but it has been moved to the main part of the heap since Java 7:
Area: HotSpot
Synopsis: In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.
RFE: 6962931
And in Java 8 Hotspot, Permanent Generation has been completely removed.
String literals are not stored on the stack. Never. In fact, no objects are stored on the stack.
String literals (or more accurately, the String objects that represent them) are were historically stored in a Heap called the "permgen" heap. (Permgen is short for permanent generation.)
Under normal circumstances, String literals and much of the other stuff in the permgen heap are "permanently" reachable, and are not garbage collected. (For instance, String literals are always reachable from the code objects that use them.) However, you can configure a JVM to attempt to find and collect dynamically loaded classes that are no longer needed, and this may cause String literals to be garbage collected.
CLARIFICATION #1 - I'm not saying that Permgen doesn't get GC'ed. It does, typically when the JVM decides to run a Full GC. My point is that String literals will be reachable as long as the code that uses them is reachable, and the code will be reachable as long as the code's classloader is reachable, and for the default classloaders, that means "for ever".
CLARIFICATION #2 - In fact, Java 7 and later uses the regular heap to hold the string pool. Thus, String objects that represent String literals and intern'd strings are actually in the regular heap. (See #assylias's Answer for details.)
But I am still trying to find out thin line between storage of string literal and string created with new.
There is no "thin line". It is really very simple:
String objects that represent / correspond to string literals are held in the string pool.
String objects that were created by a String::intern call are held in the string pool.
All other String objects are NOT held in the string pool.
Then there is the separate question of where the string pool is "stored". Prior to Java 7 it was the permgen heap. From Java 7 onwards it is the main heap.
String pooling
String pooling (sometimes also called as string canonicalisation) is a
process of replacing several String objects with equal value but
different identity with a single shared String object. You can achieve
this goal by keeping your own Map (with possibly soft
or weak references depending on your requirements) and using map
values as canonicalised values. Or you can use String.intern() method
which is provided to you by JDK.
At times of Java 6 using String.intern() was forbidden by many
standards due to a high possibility to get an OutOfMemoryException if
pooling went out of control. Oracle Java 7 implementation of string
pooling was changed considerably. You can look for details in
http://bugs.sun.com/view_bug.do?bug_id=6962931 and
http://bugs.sun.com/view_bug.do?bug_id=6962930.
String.intern() in Java 6
In those good old days all interned strings were stored in the PermGen
– the fixed size part of heap mainly used for storing loaded classes
and string pool. Besides explicitly interned strings, PermGen string
pool also contained all literal strings earlier used in your program
(the important word here is used – if a class or method was never
loaded/called, any constants defined in it will not be loaded).
The biggest issue with such string pool in Java 6 was its location –
the PermGen. PermGen has a fixed size and can not be expanded at
runtime. You can set it using -XX:MaxPermSize=96m option. As far as I
know, the default PermGen size varies between 32M and 96M depending on
the platform. You can increase its size, but its size will still be
fixed. Such limitation required very careful usage of String.intern –
you’d better not intern any uncontrolled user input using this method.
That’s why string pooling at times of Java 6 was mostly implemented in
the manually managed maps.
String.intern() in Java 7
Oracle engineers made an extremely important change to the string
pooling logic in Java 7 – the string pool was relocated to the heap.
It means that you are no longer limited by a separate fixed size
memory area. All strings are now located in the heap, as most of other
ordinary objects, which allows you to manage only the heap size while
tuning your application. Technically, this alone could be a sufficient
reason to reconsider using String.intern() in your Java 7 programs.
But there are other reasons.
String pool values are garbage collected
Yes, all strings in the JVM string pool are eligible for garbage
collection if there are no references to them from your program roots.
It applies to all discussed versions of Java. It means that if your
interned string went out of scope and there are no other references to
it – it will be garbage collected from the JVM string pool.
Being eligible for garbage collection and residing in the heap, a JVM
string pool seems to be a right place for all your strings, isn’t it?
In theory it is true – non-used strings will be garbage collected from
the pool, used strings will allow you to save memory in case then you
get an equal string from the input. Seems to be a perfect memory
saving strategy? Nearly so. You must know how the string pool is
implemented before making any decisions.
source.
As other answers explain Memory in Java is divided into two portions
1. Stack: One stack is created per thread and it stores stack frames which again stores local variables and if a variable is a reference type then that variable refers to a memory location in heap for the actual object.
2. Heap: All kinds of objects will be created in heap only.
Heap memory is again divided into 3 portions
1. Young Generation: Stores objects which have a short life, Young Generation itself can be divided into two categories Eden Space and Survivor Space.
2. Old Generation: Store objects which have survived many garbage collection cycles and still being referenced.
3. Permanent Generation: Stores metadata about the program e.g. runtime constant pool.
String constant pool belongs to the permanent generation area of Heap memory.
We can see the runtime constant pool for our code in the bytecode by using javap -verbose class_name which will show us method references (#Methodref), Class objects ( #Class ), string literals ( #String )
You can read more about it on my article How Does JVM Handle Method Overloading and Overriding Internally.
To the great answers that already included here I want to add something that missing in my perspective - an illustration.
As you already JVM divides the allocated memory to a Java program into two parts. one is stack and another one is heap. Stack is used for execution purpose and heap is used for storage purpose. In that heap memory, JVM allocates some memory specially meant for string literals. This part of the heap memory is called string constants pool.
So for example, if you init the following objects:
String s1 = "abc";
String s2 = "123";
String obj1 = new String("abc");
String obj2 = new String("def");
String obj3 = new String("456);
String literals s1 and s2 will go to string constant pool, objects obj1, obj2, obj3 to the heap. All of them, will be referenced from the Stack.
Also, please note that "abc" will appear in heap and in string constant pool. Why is String s1 = "abc" and String obj1 = new String("abc") will be created this way? It's because String obj1 = new String("abc") explicitly creates a new and referentially distinct instance of a String object and String s1 = "abc" may reuse an instance from the string constant pool if one is available. For a more elaborate explanation: https://stackoverflow.com/a/3298542/2811258
Today my colleagues and me have a discussion about the usage of the final keyword in Java to improve the garbage collection.
For example, if you write a method like:
public Double doCalc(final Double value)
{
final Double maxWeight = 1000.0;
final Double totalWeight = maxWeight * value;
return totalWeight;
}
Declaring the variables in the method final would help the garbage collection to clean up the memory from the unused variables in the method after the method exits.
Is this true?
Here's a slightly different example, one with final reference-type fields rather than final value-type local variables:
public class MyClass {
public final MyOtherObject obj;
}
Every time you create an instance of MyClass, you'll be creating an outgoing reference to a MyOtherObject instance, and the GC will have to follow that link to look for live objects.
The JVM uses a mark-sweep GC algorithm, which has to examine all the live refereces in the GC "root" locations (like all the objects in the current call stack). Each live object is "marked" as being alive, and any object referred to by a live object is also marked as being alive.
After the completion of the mark phase, the GC sweeps through the heap, freeing memory for all unmarked objects (and compacting the memory for the remaining live objects).
Also, it's important to recognize that the Java heap memory is partitioned into a "young generation" and an "old generation". All objects are initially allocated in the young generation (sometimes referred to as "the nursery"). Since most objects are short-lived, the GC is more aggressive about freeing recent garbage from the young generation. If an object survives a collection cycle of the young generation, it gets moved into the old generation (sometimes referred to as the "tenured generation"), which is processed less frequently.
So, off the top of my head, I'm going to say "no, the 'final' modifer doesn't help the GC reduce its workload".
In my opinion, the best strategy for optimizing your memory-management in Java is to eliminate spurious references as quickly as possible. You could do that by assigning "null" to an object reference as soon as you're done using it.
Or, better yet, minimize the size of each declaration scope. For example, if you declare an object at the beginning of a 1000-line method, and if the object stays alive until the close of that method's scope (the last closing curly brace), then the object might stay alive for much longer that actually necessary.
If you use small methods, with only a dozen or so lines of code, then the objects declared within that method will fall out of scope more quickly, and the GC will be able to do most of its work within the much-more-efficient young generation. You don't want objects being moved into the older generation unless absolutely necessary.
Declaring a local variable final will not affect garbage collection, it only means you can not modify the variable. Your example above should not compile as you are modifying the variable totalWeight which has been marked final. On the other hand, declaring a primitive (double instead of Double) final will allows that variable to be inlined into the calling code, so that could cause some memory and performance improvement. This is used when you have a number of public static final Strings in a class.
In general, the compiler and runtime will optimize where it can. It is best to write the code appropriately and not try to be too tricky. Use final when you do not want the variable to be modified. Assume that any easy optimizations will be performed by the compiler, and if you are worried about performance or memory use, use a profiler to determine the real problem.
No, it is emphatically not true.
Remember that final does not mean constant, it just means you can't change the reference.
final MyObject o = new MyObject();
o.setValue("foo"); // Works just fine
o = new MyObject(); // Doesn't work.
There may be some small optimisation based around the knowledge that the JVM will never have to modify the reference (such as not having check to see if it has changed) but it would be so minor as to not worry about.
Final should be thought of as useful meta-data to the developer and not as a compiler optimisation.
Some points to clear up:
Nulling out reference should not help GC. If it did, it would indicate that your variables are over scoped. One exception is the case of object nepotism.
There is no on-stack allocation as of yet in Java.
Declaring a variable final means you can't (under normal conditions) assign a new value to that variable. Since final says nothing about scope, it doesn't say anything about it's effect on GC.
Well, I don't know about the use of the "final" modifier in this case, or its effect on the GC.
But I can tell you this: your use of Boxed values rather than primitives (e.g., Double instead of double) will allocate those objects on the heap rather than the stack, and will produce unnecessary garbage that the GC will have to clean up.
I only use boxed primitives when required by an existing API, or when I need nullable primatives.
Final variables cannot be changed after initial assignment (enforced by the compiler).
This does not change the behaviour of the garbage collection as such. Only thing is that these variables cannot be nulled when not being used any more (which may help the garbage collection in memory tight situations).
You should know that final allows the compiler to make assumptions about what to optimize. Inlining code and not including code known not to be reachable.
final boolean debug = false;
......
if (debug) {
System.out.println("DEBUG INFO!");
}
The println will not be included in the byte code.
There is a not so well known corner case with generational garbage collectors. (For a brief description read the answer by benjismith for a deeper insight read the articles at the end).
The idea in generational GCs is that most of the time only young generations need to be considered. The root location is scanned for references, and then the young generation objects are scanned. During this more frequent sweeps no object in the old generation are checked.
Now, the problem comes from the fact that an object is not allowed to have references to younger objects. When a long lived (old generation) object gets a reference to a new object, that reference must be explicitly tracked by the garbage collector (see article from IBM on the hotspot JVM collector), actually affecting the GC performance.
The reason why an old object cannot refer to a younger one is that, as the old object is not checked in minor collections, if the only reference to the object is kept in the old object, it will not get marked, and would be wrongly deallocated during the sweep stage.
Of course, as pointed by many, the final keyword does not reallly affect the garbage collector, but it does guarantee that the reference will never be changed into a younger object if this object survives the minor collections and makes it to the older heap.
Articles:
IBM on garbage collection: history, in the hotspot JVM and performance. These may no longer be fully valid, as it dates back in 2003/04, but they give some easy to read insight into GCs.
Sun on Tuning garbage collection
GC acts on unreachable refs. This has nothing to do with "final", which is merely an assertion of one-time assignment. Is it possible that some VM's GC can make use of "final"? I don't see how or why.
final on local variables and parameters makes no difference to the class files produced, so cannot affect runtime performance. If a class has no subclasses, HotSpot treats that class as if it is final anyway (it can undo later if a class that breaks that assumption is loaded). I believe final on methods is much the same as classes. final on static field may allow the variable to be interpreted as a "compile-time constant" and optimisation to be done by javac on that basis. final on fields allows the JVM some freedom to ignore happens-before relations.
There seems to be a lot of answers that are wandering conjectures. The truth is, there is no final modifier for local variables at the bytecode level. The virtual machine will never know that your local variables were defined as final or not.
The answer to your question is an emphatic no.
All method and variable can be overridden bydefault in subclasses.If we want to save the subclasses from overridig the members of superclass,we can declare them as final using the keyword final.
For e.g-
final int a=10;
final void display(){......}
Making a method final ensures that the functionality defined in the superclass will never be changed anyway. Similarly the value of a final variable can never be changed. Final variables behaves like class variables.
Strictly speaking about instance fields, final might improve performance slightly if a particular GC wants to exploit that. When a concurrent GC happens (that means that your application is still running, while GC is in progress), see this for a broader explanation, GCs have to employ certain barriers when writes and/or reads are done. The link I gave you pretty much explains that, but to make it really short: when a GC does some concurrent work, all read and writes to the heap (while that GC is in progress), are "intercepted" and applied later in time; so that the concurrent GC phase can finish it's work.
For final instance fields, since they can not be modified (unless reflection), these barriers can be omitted. And this is not just pure theory.
Shenandoah GC has them in practice (though not for long), and you can do, for example:
-XX:+UnlockExperimentalVMOptions
-XX:+UseShenandoahGC
-XX:+ShenandoahOptimizeInstanceFinals
And there will be optimizations in the GC algorithm that will make it slightly faster. This is because there will be no barriers intercepting final, since no one should modify them, ever. Not even via reflection or JNI.
The only thing that I can think of is that the compiler might optimize away the final variables and inline them as constants into the code, thus you end up with no memory allocated.
absolutely, as long as make object's life shorter which yield great benefit of memory management, recently we examined export functionality having instance variables on one test and another test having method level local variable. during load testing, JVM throws outofmemoryerror on first test and JVM got halted. but in second test, successfully able to get the report due to better memory management.
The only time I prefer declaring local variables as final is when:
I have to make them final so that they can be shared with some anonymous class (for example: creating daemon thread and let it access some value from enclosing method)
I want to make them final (for example: some value that shouldn't/doesn't get overridden by mistake)
Does they help in fast garbage collection?
AFAIK a object becomes a candidate of GC collection if it has zero strong references to it and in that case as well there is no guarantee that they will be immediately garbage collected . In general, a strong reference is said to die when it goes out of scope or user explicitly reassign it to null reference, thus, declaring them final means that reference will continue to exists till the method exists (unless its scope is explicitly narrowed down to a specific inner block {}) because you can't reassign final variables (i.e. can't reassign to null). So I think w.r.t Garbage Collection 'final' may introduce a unwanted possible delay so one must be little careful in defining there scope as that controls when they will become candidate for GC.