Java-QA-GCMemory
Java-QA-GCMemory
The main drawback of Garbage Collection is that it freezes all those threads
which are currently active at the time of occurring memory recovery phase.
The garbage collection algorithms take time in seconds or minutes to run,
and due to this, garbage collection routines can't be scheduled.
The internal representation of the Java classes held by JVM is included in the
PermGen space. PermGen space contains garbage data collected in the same
way as the heap's other parts (Young generation and Old generation)
collected.
5) Explain the difference between a minor, major and full garbage
collection.
The Finalize() method is called by the garbage collector before collecting any
object that is eligible for the garbage collector. The Finalize() method is used
to get the last chance to object to cleaning and free remaining resource.
8) Can we force the Garbage collector to run at any time?
Mark and Sweep are the two states of garbage collection. In the Mark stage,
JVM identifies whether an object is still needed or not. The object is marked
for garbage collection when the object is not needed.
Yes, we can trigger the garbage collection by issuing a request to the JVM.
We use the System.gc() command for issuing the request. However, there is
no guarantee on when the JVM will respond to such a request.
17) Explain the ways for making an object eligible for GC when it
is no longer needed?
There are the following three ways to make an object eligible for GC:
When the purpose of creating an object is achieved, we can set the reference
of this object to null to make it available for GC.
Decouple the reference variable from the object and set it refer to another
object, so the object which it was referring to before reassigning is eligible
for Garbage Collection.
When we have two instance variables referring to the instance of the same
class, and these two variables also refer to each other and the object referred
by these variables don't have any other valid reference, these two objects are
eligible for GC.
The more live objects are found, the longer the suspension, which has a direct
impact on response time and throughput. This fundamental tenet of garbage
collection and the resulting effect on application execution is called the
garbage-collection pause or GC pause time.
A String instance in Java is an object with two fields: a char[] value field and
an int hash field. The value field is an array of chars representing the string
itself, and the hash field contains the hashCode of a string which is
initialized with zero, calculated during the first hashCode() call and cached
ever since. As a curious edge case, if a hashCode of a string has a zero value,
it has to be recalculated each time the hashCode() is called.
Important thing is that a String instance is immutable: you can’t get or
modify the underlying char[] array. Another feature of strings is that the
static constant strings are loaded and cached in a string pool. If you have
multiple identical String objects in your source code, they are all
represented by a single instance at runtime.
Output:
Strong reference: It is very simple as we use it in our daily programming. Any object
which has Strong reference attached to it is not eligible for garbage collection. We can
create a strong reference by using the following statement:
Weak Reference: It does not survive after the next garbage collection process. If we
are not sure when the data will be requested again. In this condition, we can create a
weak reference to it. In case, if the garbage collector processes, it destroys the object.
When we again try to retrieve that object, we get a null value. It is defined
in java.lang.ref.WeakReference class. We can create a weak reference by using the
following statement:
Soft Reference: It is collected when the application is running low on memory. The
garbage collector does not collect the softly reachable objects. All soft referenced
object s are collected before it throws an OutOfMemoryError. We can create a soft
reference by using the following statement:
1. SoftReference<StringBuilder> reference = new SoftReference<>(new StringB
uilder());
**Throughput Target: The time spent during the garbage collection versus the time
spent outside of garbage collection is called throughput target.
AD
We can use multiple CPUs for better application throughput. We should use a CMS
garbage collector if we have more CPUs for use. Hence, it has an advantage over the
parallel garbage collector. If you want to use a CMS garbage collector, execute the -
XX:+USeParNewGC JVM argument to activate it. We can also set the number of GC
threads by using the -XX:ParallelCMSThreads=<n> JVM argument.
The Eden, survivors, and old areas use this equal-sized region for the memory
allocation of the objects. Apart from these memory regions, there are two more types
of regions presented in the G1 GC:
G1 GC shows a concurrent global marking phase to determine the live and dead objects
throughout the heap. After the completion of the mark phase, G1 collects the
information of regions that contains the most garbage objects. After that these regions
are swept first. If you want to use the G1 garbage collector, execute the -
XX:+UseG1GC JVM argument to activate it.
Z Garbage Collector
ZGC is a scalable low-latency garbage collector that debuted in Java 11 as
an experimental option for Linux. JDK 14 introduced ZGC under the
Windows and macOS operating systems. ZGC has obtained the production
status from Java 15 onwards.
ZGC performs all expensive work concurrently, without stopping the
execution of application threads for more than 10 ms, which makes it
suitable for applications that require low latency. It uses load barriers with
colored pointers to perform concurrent operations when the threads are
running, and they’re used to keep track of heap usage.
Reference coloring (colored pointers) is the core concept of ZGC. It means
that ZGC uses some bits (metadata bits) of reference to mark the state of
the object. It also handles heaps ranging from 8MB to 16TB in size.
Furthermore, pause times don’t increase with the heap, live-set, or root-set
size.
Similar to G1, Z Garbage Collector partitions the heap, except that heap
regions can have different sizes.
To enable the Z Garbage Collector, we can use the following argument
in JDK versions lower than 15:
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC Application.javaCopy
From version 15 on, we don’t need experimental mode on:
java -XX:+UseZGC Application.javaCopy
We should note that ZGC isn’t the default Garbage Collector.
JIT in Java
When we write a program in any programming language it requires converting that
code in the machine-understandable form because the machine only understands the
binary language. According to the programming languages, compiler differs. The
compiler is a program that converts the high-level language to machine level code.
The Java programming language uses the compiler named javac. It converts the high-
level language code into machine code (bytecode). JIT is a part of the JVM that
optimizes the performance of the application. JIT stands for Java-In-Time Compiler.
The JIT compilation is also known as dynamic compilation. In this section, we will
learn what is JIT in Java, its working, and the phases of the JIT compiler.
o Method In-lining
o Local Optimizations
o Control Flow Optimizations
o Constant Folding
o Dead Code Elimination
o Global Optimizations
o Heuristics for optimizing call sites
AD
o Java Development Kit (JDK) provides the Java compiler (javac) to compile the Java
source code into the bytecode (.class file). After that, JVM loads the .class file at runtime
and transform the bytecode into the binary code (machine code). Further, the machine
code is used by the interpreter.
o We know that the interpretation of Java bytecode reduces the performance of the
native application. It is the reason to implement the JIT compiler. The JIT compiler
accelerates the performance of the application by compiling the bytecode into native
machine code.
o It is enabled by default when a method is invoked. The JVM directly invokes the
compiled code of the method without interpreting it. It does not require much memory
usage.
Therefore, the JIT compiler boosts the performance of the native application. We can
understand the working of the JIT compiler with the help of the following flow chart.
The following figure shows the functional relationship of the JIT compiler
with JRE and JVM.
Optimization Levels
It is also known as the optimization level. Each level provides a certain level of
performance. JIT compiler provides the following level of optimization:
o Cold: It used during the startup of the large Java application. The goal is to achieve the
best-compiled code speed.
o Warm: After the starting of the Java application, most of the methods compiled when
they reach the invocation threshold.
o Hot: The methods that consume more than 1% are scheduled for hot compilation.
o Very Hot: The method scheduled for a very hot if they are not scorching but hot.
o Scorching: The methods that consume more than 5% are scheduled for scorching
compilation.
The default and initial optimization levels are warm. We get better performance if the
optimization level is hotter but it increases the cost in terms of memory and CPU.
At the higher optimization level, the virtual machine uses a thread called sampling. It
identifies the methods that take a long time to execute. The higher optimization level
includes the following techniques:
o Escape Analysis
o Partial Redundancy Elimination
The above techniques use more memory and CPU to improve the performance of the
Java application. It increases the cost of compilation but compensates for performance.