Pages

April 06, 2016

#Java: Part 9-Core Java Interview Questions and Answers(Java Memory Model, Garbage Collectors in Java)

> > Part 7-Core Java Interview Questions and Answers

What is JIT compiler in Java?
  • JIT stands for Just-In-Time compiler. 
  • It is a program that helps in converting the Java bytecode into instructions that are sent directly to the processor. 
  • The JIT compiler is by default enabled and is activated whenever a Java method is invoked. The JIT compiler then compiles the bytecode of the invoked method into native machine code, compiling it 'just in time' to execute. 
  • Once the method has been compiled, the JVM summons the compiled code of that method directly rather than interpreting it. This is why it is often responsible for the performance optimization of Java applications at the run time.
Which are the different segments of memory ?
  • Stack Segment : contains local variables and Reference variables(variables that hold the address of an object in the heap)
  • Heap Segment : contains all created objects in runtime, objects only plus their object attributes (instance variables)
  • Code Segment :  The segment where the actual compiled Java bytecodes resides when loaded.
Describe what happens when an object is created in Java ?
1. Memory is allocated from heap to hold all instance variables and implementation-specific data of the object and its superclasses. Implementation-specific data includes pointers to class and method data.
2. The instance variables of the objects are initialized to their default values.
3. The constructor for the most derived class is invoked. The first thing a constructor does is call the constructor for its superclasses. This process continues until the constructor for java.lang.Object is called, as java.lang.Object is the base class for all objects in java.
4. Before the body of the constructor is executed, all instance variable initializes and initialization blocks are executed. Then the body of the constructor is executed. Thus, the constructor for the base class completes first and constructor for the most derived class completes last.

Permanent Generation
  • Permanent Generation or 'Perm Gen' is replaced by Metaspace since Java 8.
  • There are two memory regions in the JVM: the heap and the stack. Local variables and methods reside on the stack, everything else on the heap.
  • Java objects are created in Heap and Heap is divided into three parts or generations for the sake of garbage collection in Java, these are called as Young or New generation, Tenured or Old Generation and Perm Area of the heap.
  • New Generation is further divided into three parts known as Eden space, Survivor 1 and Survivor 2 space. When an object first created in heap its gets created in new generation inside Eden space and after subsequent minor garbage collection if an object survives its gets moved to survivor 1 and then survivor 2 before major garbage collection moved that object to old or tenured generation.
  • Since permanent generation is a separate region, it is not considered part of the Java Heap space. Objects in this space are relatively permanent. 
  • Also Perm space is used to keep information (metadata) for loaded classes and few other advanced features like String Pool(for highly optimized string equality testing), which usually get created by String.intern() methods.
  • Objects in PermGen survive forever, and this region is never garbage collected. This means if the permgen is out of space, then our application will crash.
Here is now we can set size of Perm Gen
  • -Xms : Sets the initial heap size for when the JVM starts.
  • -Xmx : Sets the maximum heap size.
  • -Xmn : Sets the size of the Young Generation.
  • -XX:PermSize : Sets the starting size of the Permanent Generation.
  • -XX:MaxPermSize : Sets the maximum size of the Permanent Generation
e.g  we create a new object, StudentDetails std = new StudentDetails(); after executing the line above memory status will be like this.
  • Heap: stores "new StudentDetails()"
  • Stack: stores information about "std"
  • Perm Space: stores information about StudentDetails class
How to deal with java.lang.OutOfMemoryError?
OutOfMemoryError: PermGen Space error occurs when the permanent generation heap is full. Although this error can occur in normal circumstances, usually, this error is caused by a memory leak. In short, such a memory leak means that a classloader and its classes cannot be garbage collected after they have been undeployed/discarded.

We can avoid OutOfMemoryError: PermGen by:
1). Increasing the maximum size of the permgen heap: Permanent generation of the heap is used to store String pool and various Metadata required by JVM related to Class, method and other java primitives. Since in most of JVM default size of Perm Space is around "64MB" you can easily run out of memory if you have too many classes or a huge number of Strings in your project. It doesn't depend on –Xmx value, so no matter how big your total heap size you can run OutOfMemory in perm space.

We can specify the size of permanent generation using JVM options "-XX: PermSize" and  "-XX: MaxPermSize" based on your project need, e.g: export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m"

2). Also we need to make sure not to write classes that have static variables keeping references to class definitions.

FYI, static variables and their technical values (primitives or references) are stored in PermGen space. If the 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.

From Java 8 onwards, the static variables are stored in the Heap itself. PermGen Space have been removed and new space named as MetaSpace is introduced which is not the part of Heap. 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.

We can solve java.lang.OutOfMemoryError: Java heap space in 2 ways:
1). Increase the maximum heap size by using JVM options "-Xmx512M". Its better to keep -Xmx to -Xms ration either 1:1 or 1:1.5 if you are setting heap size in your java application. e,g: export JVM_ARGS="-Xms1024m -Xmx1024m".

2). If you are still getting the error even after increasing the heap size then, best way is to check your application (can use Eclipse Memory Analyzer to examine your heap dump) and look for any memory leak.

Suppose, we have a website and our code is deployed on the tomcat server. We made some changes in a few classes and redeploy the new version on server, even though most of the classes are unchanged yet a new complete set of metadata all the classes is created in the PermGen. At the same time, the meta-data of the previous deployment stays in PermGen (and never been referred to). Because there is no Garbage collection on PermGen, the old (un-referred) metadata will not be cleaned. That's why of we keep on redeploying the application again and again, eventually the PermGen space will be full. To avoid this we need to stop and restart the services, each time we do the redeployment. This happens if you are using 1.6 or the earlier version of Java.

In Java 7, internalized strings are no longer stored in PermGen. They will stay in Old Generation of the Heap and can be Garbage collected. So if you are using Java 1.7 and your code is creating lots of Strings it will never result in PermGen error.

In Java 8, PermGen is moved all together. Instead a new 'metaspace' is introduced, which is where meta data of classes are placed.

Metaspace
  • Perm Gen' is replaced by Metaspace in Java 8, that means there is no Perm Gen, which means there is no more “java.lang.OutOfMemoryError: PermGen” space problems.
  • Unlike Perm Gen which resides in the Java heap, Metaspace is not part of the heap. 
  • It is allocated out of your computer's native memory, so the maximum available space for the metaspace is the total available system memory for your computer. 
  • Metaspace by default auto increases its size (up to what the underlying OS provides), while Perm Gen always has fixed maximum size. 
  • Two new flags can be used to set the size of the metaspace, they are: “-XX:MetaspaceSize” and “-XX:MaxMetaspaceSize”. 
  • The theme behind the Metaspace is that the lifetime of classes and their metadata matches the lifetime of the classloaders. That is, as long as the classloader is alive, the metadata remains alive in the Metaspace and can’t be freed.
  • When the classes are no longer createable, the metadata related to those classes is then removed. That means, when we redeploy the application all the metadata related to the previous deployment will be removed.
Code Cache
  • When a Java program is run, it executes the code in a tiered manner. 
  • In the first tier, it uses client compiler (C1 compiler) in order to compile the code with instrumentation. 
  • The profiling data is used in the second tier (C2 compiler) for the server compiler, to compile that code in an optimized manner. 
  • Tiered compilation is not enabled by default in Java 7, but is enabled in Java 8.
  • The Just-In-Time (JIT) compiler stores the compiled code in an area called code cache. It is a special heap that holds the compiled code.
  • This area is flushed if its size exceeds a threshold and these objects are not relocated by the GC.
Method Area
  • Method area is part of heap.
  • It is common across all the threads
  • Its the place where our compiled class are stored. It contains per-class elements like constant pool, fields, method local data, method code, constructor codes etc. which are used in class and initialization of objects/interfaces.
  • The method area gets created during JVM start-up. 
  • It could be of fixed size or vary. 
  • Its memory may not be contiguous.
  • JVM implementation can give control to programmer over Method area creation, its sizing etc. If method area memory is not sufficient to satisfy an allocation request then JVM throws OutOfMemoryError.
Native Memory
It is separate memory area where all other language specific code resides. e.g: socket connection.

PC Register
  • It stores the sequence of information or instructions which need to executed next.
  • There is one PC Register created per thread, it tells the thread what it need to do next.
Memory Pool
  • Memory Pools are created by JVM memory managers to create pool of immutable objects.
  • Memory Pool can belong to Heap or Perm Gen, depending on JVM memory manager implementation.
Runtime Constant Pool
Runtime constant pool is a per-class runtime representation of constant pool in a class. It contains class runtime constants and static methods. Runtime constant pool is part of the method area.

Java Stack Memory
  • Java stack memory is used for execution of a thread. 
  • It contain method specific values that are short-lived and references to other objects in the heap that are getting referred from the method.
Stack vs Heap
  • Heap memory is used by java run-time to allocate memory to Objects and JRE classes. Whenever we create any object, it’s always created in the Heap space. Garbage Collection runs on the heap memory to free the memory used by objects that doesn’t have any reference. Any object created in the heap space has global access and can be referenced from anywhere of the application.
  • Java Stack memory is used for execution of a thread. It 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.
  • Each Thread in Java has their own stack which can be specified using -Xss JVM parameter, similarly, you can also specify heap size of Java program using JVM option -Xms and -Xmx where -Xms is starting size of the heap and -Xmx is a maximum size of java heap.
  • If there is no memory left in the stack for storing function call or local variable, JVM will throw java.lang.StackOverFlowError, while if there is no more heap space for creating an object, JVM will throw java.lang.OutOfMemoryError: Java Heap Space.
  • Stack memory is a lot lesser than the size of  heap memory in Java.
  • If you are using Recursion, on which method calls itself, You can quickly fill up stack memory.
  • Variables stored in stacks are only visible to the owner Thread while objects created in the heap are visible to all thread. In other words, stack memory is kind of private memory of Java Threads while heap memory is shared among all threads.
  • Stack memory is short-lived whereas heap memory lives from the start till the end of application execution.
  • Suppose you declare a local primitive variable 'age' and assign it the value '21'. Since it's the local variable and is a primitive, it will be stored in a stack. Now you declare another variable 'name' of type String and assign it a value 'Hello'. Since String is an Object it will be stored in the heap. First create a string with a value 'Hello' in heap (if its not present in String Pool). And then variable in Stack will created, which will points towards the String Object present in Heap.
  • Let's take another example to see how variables and objects are stored in Heap and Stack. Inside the main method we declare an List and add three strings in it. We are calling another method to print the List.
public static void main(String[] args) {
List < String > myList=new ArrayList < String > ();
myList.add("One");
myList.add("Two");
myList.add("Three");
printList(myList);
}

private static void printList(List < String > data) {
System.out.println(data);
}

Now, we will make a small change in our printList method, we will first extract the 1st String stored in the list and then add another String in the list.

private static void printList(List < String > data) {
String value=data.get(1);
data.add("Four");
System.out.println(value);
}

Once printList() is executed successfully, the local variables 'value' and 'data' will be popped up from the stack.

How do we find memory usage from Java program?
We can use memory related methods from java.lang.Runtime class to get the free memory, total memory and maximum heap memory in Java. By using these methods, we can find out how many percents of the heap is used and how much heap space is remaining.
  • Runtime.freeMemory() return amount of free memory in bytes
  • Runtime.totalMemory() returns total memory in bytes
  • Runtime.maxMemory() returns maximum memory in bytes.
What are the available types of Garbage Collectors in Java?
  • Garbage Collection is the process of freeing space in the heap for allocation of new objects. 
  • Garbage Collector is the program running in the background that looks into all the objects in the memory and find out objects that are not referenced by any part of the program. All these unreferenced objects are deleted and space is reclaimed for allocation to other objects.
  • Garbage Collector is a Daemon thread that keeps running in the background. 
 Garbage Collection involve following steps:
  •  Mark: Starts from root node of application (main), walks the object graph, mark objects that are reachable as live.
  •  Sweep/ Delete: Delete unreachable objects.
  •  Compacting: Compact the memory by moving around the objects and making the allocation contiguous than fragmented.
There are five Garbage collectors available:
1). Serial Garbage Collector
  • It is the default for client style machines in Java SE 5 and 6. 
  • It works by holding all the application threads in ‘Stop the World’ fashion ( the execution of application is paused while the collection of garbage takes place). 
  • It can be used when we simply mark and delete objects from young and old generations.
  • It is useful for client machines such as our simple standalone application or in machines with a smaller CPU like our laptops.
  • It is good for small applications with low memory foot prints, because it is directly going to identify the objects and delete them from the heap. 
  • It cannot be used in a large scale applications where we have large number of threads running on the heap. The way it works by freezing all the application threads while doing garbage collection may not be suitable for a server environment. 
  • Turn on the -XX:+UseSerialGC JVM argument to use the serial garbage collector.
2). Parallel garbage collector
  • It is also called as throughput collector.
  • Unlike serial garbage collector, this uses multiple threads for garbage collection. Similar to serial garbage collector this also freezes all the application threads while performing garbage collection. N number of threads are based on number of CPU cores present in the system. If required we can control these number of threads.
  • The number of garbage collector threads can be controlled with command-line options: -XX:ParallelGCThreads=< desired number >
  • Parallel GC uses only 1 thread for the old generation (less chances that the objects are garbage collected that's why only one thread is used) and multiple threads for the young generation.
3). Parallel old garbage collector
  • Parallel Old GC is same as Parallel GC, but here for both old and young generations multiple threads are used for garbage collection. 
4). Concurrent Mark Sweep (CMS) garbage collector 
  • Also known as Concurrent low pause collectors.
  • It uses multiple threads to scan the heap memory to mark instances for eviction and then sweep the marked instances. It attempts to minimize the pauses due to garbage collection by doing most of the garbage collection work concurrently with the application threads.
  • It does the garbage collection for the old generation only. The young generation uses same algorithm of parallel garbage collector 
  • In comparison with parallel garbage collector, CMS collector uses more CPU to ensure better application throughput. If we can allocate more CPU for better performance then CMS garbage collector is the preferred choice over the parallel collector.
  • To enable the CMS Collector use -XX:+UseConcMarkSweepGC and to set the number of threads use -XX:ParallelCMSThreads=< desired number > 
5). G1 garbage collector 
  • G1 means Garbage first.
  • The Garbage First or G1 garbage collector is available in Java 7 and is designed to be the long term replacement for the CMS collector. 
  • G1 GC is default garbage collector in Java 9.
  • The G1 collector is a parallel, concurrent, and incrementally compacting low-pause garbage collector that has quite a different layout from the other garbage collectors described previously.
  • There is no concept of young and old generations in case of G1. It divides the heap space into multiple equally sized heaps regions and whenever the garbage collection involved it first go to the region which has lesser number of live data. That's why it is known as garbage first. 
  • G1 also does compacts the free heap space on the go just after reclaiming the memory. But CMS garbage collector compacts the memory on stop the world (STW) situations.
  • It can be turned on by setting –XX:+UseG1GC JVM argument.
What is difference between ParNew and DefNew Young Generation Garbage collector?
  • ParNew and DefNew is two young generation garbage collector. 
  • ParNew is a multi-threaded GC used along with concurrent Mark Sweep while DefNew is single threaded GC used along with Serial Garbage Collector.
What is the difference between a soft reference and a weak reference in Java?
Garbage Collector reclaims memory from objects which are eligible for garbage collection and this eligibility is decided based upon which kind of references are pointing to that object.
For those uninitiated, there are four kind of reference in Java: Strong, weak, soft, phantom.

Strong Reference is most simple as we use it in our day to day programming life e.g. in the code, String city = "Nuremberg" , reference variable city has strong reference to String object "Nuremberg". Any object which has Strong reference attached to it is not eligible for garbage collection, because these are objects which is needed by Java program.

Weak Reference are represented using java.lang.ref.WeakReference class. You can create weak by:
City city = new City(); // strong reference
WeakReference weakCity = new WeakReference(city); //weak reference
/* as soon as you declare 'city=null', City object will become eligible for garbage collection
city = null;


If instead of WeakReference, Soft Reference is used then City object is not garbage collected until JVM absolutely needs memory. Soft reference in Java is represented using java.lang.ref.SoftReference class. e.g:
City city = new City(); // strong reference
SoftReference softCity = new SoftReference(city); //soft reference
city = null;


That means, Garbage collector can collect an object if only weak references are pointing towards it and they are eagerly collected, on the other hand Objects with SoftReference are collected when JVM absolutely needs memory. SoftReference are more suitable for caches and WeakReference are more suitable for storing meta data

WeakHashMap is an example of WeakReference, which is another implementation of Map interface like HashMap or TreeMap but with one unique feature. WeakHashMap wraps keys as WeakReference which means once strong reference to actual object removed, WeakReference present internally on WeakHashMap doesn't prevent them from being Garbage collected.

Phantom reference is available in java.lang.ref package and is represented by java.lang.ref.PhantomReference class. Object which only has Phantom reference pointing them can be collected whenever Garbage Collector likes it.
City city = new City(); // strong reference
PhantomReference phantomCity = new PhantomReference(city);
city = null;


In the order of strength, the references can be arranged as, Strong References > Soft References > Weak References > Phantom References.

What is a class loader? What are the different class loaders used by JVM ?
It is a subsystem of Java Virtual Machine, dedicated to loading class files when a program is executed; ClassLoader is the first to load the executable file.

Bootstrap , Extension and System are the class loaders used by JVM.

Bootstrap ClassLoader is responsible for loading standard JDK class (like java.lang, java.util etc) files from rt.jar and it is parent of all class loaders in Java. Bootstrap class loader don't have any parents, if you call String.class.getClassLoader() it will return null and any code based on that may throw NullPointerException in Java. Bootstrap class loader is also known as Primordial ClassLoader in Java.

Extension ClassLoader delegates class loading request to its parent, Bootstrap and if unsuccessful, loads class form JAVA_HOME/jre/lib/ext directory or any other directory pointed by java.ext.dirs system property. Extension ClassLoader in JVM is implemented by  sun.misc.Launcher$ExtClassLoader.

System or Application class loader is the third default class loader used by JVM to load Java classes and it is responsible for loading application specific classes from CLASSPATH environment variable, -classpath or -cp command line option, Class-Path attribute of Manifest file inside JAR. Application class loader is a child of Extension ClassLoader and its implemented by sun.misc.Launcher$AppClassLoader class. Also, except Bootstrap class loader, which is implemented in native language mostly in C,  all  Java class loaders are implemented using java.lang.ClassLoader.

Explain java.lang.OutOfMemoryError?
This Error is thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

ALSO CHECKCore Java Interview Questions And Answers

-K Himaanshu Shuklaa..

1 comment:

  1. Thank you , very useful for my interview

    ReplyDelete