Cosmic Module

J

Qubits of DPK

March 14, 2026

Core Java

Layman Explanation

Your desk = Stack. Things you're currently working on, temporary, limited space, cleared when done. Warehouse = Heap. Large long-term storage, things stay until no longer needed.

Two Memory Areas

javascript
QUBITS OF DPK
1JVM Memory
23├── Stack
4│   ├── Method call frames
5│   ├── Local variables
6│   ├── Primitive values
7│   └── Object references (addresses)
89└── Heap
10    ├── All objects (created with 'new')
11    ├── Instance variables
12    ├── Arrays
13    └── String Pool

Memory Visualization

java
QUBITS OF DPK
1int age = 25;                // age = 25 in STACK
2Car myCar = new Car();       // myCar reference in STACK
3                             // Car object in HEAP
4myCar.brand = "Toyota";      // brand stored in HEAP (inside object)
javascript
QUBITS OF DPK
1STACK                    HEAP
2────────────────         ─────────────────────────
3age = 25                 Car Object:
4myCar ─────────────►    brand = "Toyota"
5                         speed = 0

Stack Frame Lifecycle

javascript
QUBITS OF DPK
1main() called      → Stack Frame created
2  add(5,10) called → new Frame pushed on top
3  add() returns    → Frame DESTROYED
4main() ends        → Frame DESTROYED

Garbage Collection

java
QUBITS OF DPK
1Car c = new Car();
2c = null;     // reference removed
3// Car object unreachable → GC eligible
GC runs automatically. You can suggest System.gc() but JVM may ignore it.

String Pool

java
QUBITS OF DPK
1String a = "Deepak";           // String Pool
2String b = "Deepak";           // SAME Pool object
3String c = new String("Deepak"); // NEW heap object
4
5a == b         // true  (same pool object)
6a == c         // false (different heap objects)
7a.equals(c)    // true  (same content)

Stack is Per Thread, Heap is Shared

javascript
QUBITS OF DPK
1Thread 1 → own Stack
2Thread 2 → own Stack
3Thread 3 → own Stack
4All threads → SHARE one Heap
5
6⚠️ Shared heap = race conditions in multithreading
7Why synchronization exists!

Comparison Table

Real Production Story

When Deepak's notification microservice crashed in production — 1 lakh alerts loaded into heap at once — OutOfMemoryError. Quick fix: increase heap from 512MB to 2GB. Real fix: paginate the query so only chunks load at a time. Heap usage stays constant regardless of alert volume. This is senior engineer thinking.

️ All Traps

java
QUBITS OF DPK
1// Trap 1 — Primitives in methods are stack-only
2void change(int n) { n = 100; }  // original unchanged
3
4// Trap 2 — Object reference in stack, object in heap
5Car car = new Car();  // 'car' → stack, Car object → heap
6
7// Trap 3 — Reference sharing
8Car a = new Car();
9Car b = a;           // same heap object!
10b.speed = 100;
11System.out.println(a.speed);  // 100!
12
13// Trap 4 — null reference
14Car c = null;
15c.accelerate();      // ❌ NullPointerException
16
17// Trap 5 — Instance vars live in heap (survive method calls)
18class Counter {
19    int count = 0;   // heap — survives across methods!
20}

Interview Answer (SDE-2)

"JVM has two main memory areas. Stack is fast, small, per-thread, and manages method frames via LIFO — a frame is pushed on call and popped on return. It stores local variables, primitive values, and object references. Heap is large, shared across threads, managed by GC, and stores all objects and arrays. Reference variable lives in stack but actual object is in heap. String literals go to String Pool in heap — identical literals share same object for efficiency. StackOverflowError on stack exhaustion, OutOfMemoryError on heap exhaustion."

Interview Questions & MAANG-Level Answers

Q1. Where are objects stored — stack or heap?
Objects are stored in the Heap. The reference variable (pointer to the object) lives in the Stack. Car myCar = new Car()myCar (4/8 bytes reference) is in stack, the Car object with all its fields is in heap. Heap is shared across all threads. Stack is private per thread. GC manages heap; stack is managed automatically via LIFO.
Q2. What is a stack frame?
A stack frame is created for every method invocation and contains: the method's local variables, parameters, return address, and operand stack for intermediate calculations. Frames are pushed on call and popped on return. Since each thread has its own stack, method calls in different threads are completely isolated. Stack size is typically 512KB-1MB — deep recursion exceeds this, causing StackOverflowError.
Q3. What is the String Pool and why does it exist?
String Pool is a special cache in Heap where String literals are stored and reused. When you write String a = "hello"; String b = "hello";, both point to the SAME "hello" object in the pool. This saves memory since strings are immutable and can be safely shared. new String("hello") bypasses the pool and creates a new heap object. String.intern() can manually add a string to the pool.
Q4. Why is heap shared between threads dangerous?
All threads share the same heap, so multiple threads can read and write the same objects simultaneously. Without synchronization, this causes race conditions — inconsistent data, lost updates. Example: two threads both doing count++ (read-increment-write are 3 separate steps) — one thread's increment can overwrite the other's. Solutions: synchronized blocks, volatile variables, AtomicInteger, or concurrent data structures like ConcurrentHashMap.
Q5. What causes StackOverflowError vs OutOfMemoryError?
StackOverflowError: call stack is full — caused by infinite/deep recursion where method calls keep adding frames until stack space is exhausted. Fix: add base case, reduce recursion depth, or increase stack size with -Xss. OutOfMemoryError: heap is full — caused by creating too many objects, memory leaks (objects referenced but not used), or loading massive data into memory. Fix: increase heap with -Xmx, fix memory leaks, use pagination/streaming for large data (as you did in your notification service!).