This repo holds:
- MCQs for Java deep dives
- Thread Profiling Using VisualVM
- GC and Heap PDF
=======
- JMX : JMX (Java Management Extensions) is a technology used for monitoring and managing Java applications, facilitating tasks like performance monitoring, configuration management, and remote control through standardized interfaces and components.
- RMI: RMI (Remote Method Invocation) is a Java API allowing communication between Java objects in different JVMs over a network, enabling distributed application development.
- javaw:
w
stands for windowed. It is a tool used to run Java applications without showing a command prompt window. It's handy for applications with graphical interfaces or background services that don't need a visible console.
=======
- Using
new
memory is allocated on Heap, but refs exist on Stack - String pool is part of Java heap
- Stack stores intermediate results for methods
- Each thread has its own thread. Especially take care on servers, since servers are intended to be 24x7
- Each thread has separate set of CPU registers and execution state but can share shared code and heap
- Method Area stores code (ctor, variables etc.)
- JNI (Java Native Interface) facilitates the interaction between Java and native code, the Native Method Area is where information about native methods is stored within the JVM
- Program counter is used by JVM the next instruction to be executed
The JVM provides runtime services such as memory management, garbage collection, and security checks during program execution & hardware abstraction and hence called virtual machine. Compiled C++ programs produce standalone executables that do not rely on a separate runtime environment. They interact directly with the underlying operating system and hardware without an intermediary layer like a virtual machine.
Need to prevent segmentation fault
and memory leak
issues
System.gc() == Runtime.getRuntime().gc()
(Above calls induce full GC, which may suspend threads, use -XX:+DisableExplicitGC
and prefer never to call GC explicitly)
S0
,S1
= servival memory andPerm
= permanent memory andXms
= X min,Xmx
= X max
- Memory pool used for immutable objects can belong to heap or perm memory
- New objects always created in nursery (aka young gen) (Eden, S0, S1)
- How GC happens
Objects are copied to S0 from Eden so that fragments are not created and Eden can start fresh altogether.
- If an object survives multiple GC cycles, it is long living and hence promoted to old gen heap area to avoid moving from Eden -> S0 -> S1
- When orange line goes up/blue line goes down, that means GC is happening: -
Using CLI, pass as java -Xms2560m MyCls
(sets the initial heap size to 2560 megabytes)
Can heapdump in VisualVM to store heap info at a moment.
- There is no class unloading mechanism. So a class once loads remains in method area. And so do static variables. But if we create our own class loader, once that is removed, loaded classes are GCed
- JVM does not load class until needed.
import
does not mean loading, it is just for JVM to know location of class - 4 Types of GC roots: local vars, static vars, JNI refs and active Java threads
- Once mark and sweep is done, compaction is done to remove fragments
HotSpot JVM provides:
- Serial GC: does mark-sweep and compaction. Only one thread
- Parallel GC: Used to be JVM default till Java8. Uses multiple threads
-XX:ParallelGCThreads=<N>
, select-XX:+UseParallelGC
. It uses Stop-the-World strategy - Concurrent Mark and Sweep (CMS): Does not use stop the world strategy but stops threads, if changes happen in heap
- G1: Now default GC from Java9. Designed for multiprocessor, large memory systems. Divides heap in equal size spaces and firstly reclaims spaces which are mostly empty. It suspends threads only briefly
- Create local var
- Nullify ref
- Reassign ref
- Create anonymous ref
- Loading means reading from disk and storing binary data in method area
- JVM stores info like fully-qualified name of class and immediate parent class, ctor, method, variable, modifiers infos, whether
.class
is class, interface or enum - For each loaded class, an object is created in heap
ClassLoader
is abstract class. From Oracle documentation:
- JVM checks sanity of bytecode (like formatting)
- Replaces symbolic names (variable names) with actual memory refs
- Static variables are initialized from Parent -> Child order
- Bootstrap - Written in C/C++ (Native). Loads
rt.jar
classes likejava.lang
,java.util
,java.io
andjava.net
(rt = runtime) - Extension - loads extensions (additional APIs, libraries, and tools that are not part of the standard Java distribution but are commonly used in Java development) from
ext
folder - Application or System
Parent to Child relationship: Bootstrap -> Extension -> Application/System
Delegation happens to parent and if parent is not able to load, it delegates back to child (as shown below)
Otherwise ClassNotFoundException
is thrown:
ThreadLocal
in Java provides thread-local variables. These are variables that are only visible and accessible to the thread that sets them. Each thread has its own, independently initialized copy of the variable.
- Do not create object unless needed. And create object just before its usage
- Make methods static which do not use instance data, so that they can be called as
Cls.method()
and no need to create obj of class (Object creation is heavy process, need to go up hierarchy to call all ctors) - Use right GC for your app - can have stop-the-world event? Want to use multiprocessor?
- For one time use, create anonymous objects
public class AnonymousObjectExample {
public static void main(String[] args) {
// Creating an anonymous object of the Person class
new Person().introduce(); // Anonymous object calling the method directly
}
}
class Person {
public void introduce() {
System.out.println("Hi, I am Gaurav's anonymous person!");
}
}
- Release variable when no longer needed by setting to
null
- Use try-with-resource
AutoCloseable
interface resource management utility. So no need to close resources by makingfinally
block - Static fields are GC roots, which means they are never garbage-collected. So, never use mutable static fields — use only constants.
- Use helper clases - At times it is possible to have a class with lot of static variables and methods. Split these classes into smaller classes so that only those classes which are being used are loaded in the memory
- Use
StringBuilder
if possible. Also avoid wrapper and BigInteger (or similar) classes if possible - Since recursion can create lot of local vars, do not use recursion, if loop is feasible
- Optimize SQL queries - use indexes, use conditional retrievals, try avoiding too many joins, use joins over subqueries
- If multiple checks on String validations, instead of if-else, use regex
- JPA vs JDBC - JDBC is lower layer to manually interact with DB. JPA's implementation like Hibernate provides more OO way and caching, lazy loading and auto schema generation capabilities.