Lesson Completion
Back to course

Object Creation and Memory Allocation: How Java Manages Objects

Beginner
12 minutes4.9Java

1. The Hook (The "Byte-Sized" Intro)

  • In a Nutshell: Object creation = 4 steps: (1) Class loading, (2) Memory allocation, (3) Initialization, (4) Reference assignment.
  • Allocation: Starts in Eden space (Young Gen). TLAB (Thread-Local Allocation Buffer) = fast, lock-free allocation per thread.
  • Object layout: Header (mark word + class pointer) + instance data + padding.
  • String pool: Interned strings (literals) in heap, shared, memory-efficient. intern() adds to pool.
  • Key: Objects start young, promoted if survive!

Think of factory production line. Eden = assembly area (new products). TLAB = worker's personal workstation (no waiting for shared tools). String pool = parts warehouse (reuse common parts, don't duplicate). Object header = product barcode (metadata)!


2. Conceptual Clarity (The "Simple" Tier)

💡 The Analogy

  • Eden Space: Nursery (newborns arrive here)
  • TLAB: Personal baby crib (per-thread, no sharing)
  • String Pool: Library (borrow books, don't buy duplicates)

3. Technical Mastery (The "Deep Dive")

Object Creation Steps

StepActionLocation
1. Class LoadingLoad class if not loadedMetaspace
2. Memory AllocationAllocate spaceEden (TLAB)
3. InitializationSet default valuesHeap
4. ConstructorRun constructorHeap
5. Reference AssignmentAssign to variableStack (reference)

4. Interactive & Applied Code

java
public class ObjectCreationDemo { public static void main(String[] args) { demonstrateCreation(); demonstrateStringPool(); demonstrateTLAB(); } // Object creation process static void demonstrateCreation() { System.out.println("=== OBJECT CREATION ==="); // Step 1: Class loading (if not already loaded) // Step 2: Memory allocation in Eden (via TLAB) // Step 3: Default initialization (name=null) // Step 4: Constructor runs Person p = new Person("Alice"); // Reference 'p' on stack, object in Eden (heap) System.out.println(p.name); } // String pool demonstration static void demonstrateStringPool() { System.out.println("\n=== STRING POOL ==="); // String literals → String pool String s1 = "Hello"; // Created in pool String s2 = "Hello"; // Reuses s1 (same object!) System.out.println("s1 == s2: " + (s1 == s2)); // true (same reference) // new String() → Regular heap String s3 = new String("Hello"); // New object in heap System.out.println("s1 == s3: " + (s1 == s3)); // false (different objects) // intern() → Add to pool String s4 = s3.intern(); // Returns pool reference System.out.println("s1 == s4: " + (s1 == s4)); // true (pool reference) // Memory savings String[] messages = new String[1000]; for (int i = 0; i < 1000; i++) { messages[i] = "Message"; // ✅ All share same pool object! } // Only 1 "Message" object vs 1000 if using new String() } // TLAB demonstration (conceptual) static void demonstrateTLAB() { System.out.println("\n=== TLAB (Thread-Local Allocation Buffer) ==="); // Multiple threads allocating objects Runnable task = () -> { // Each thread has its own TLAB for (int i = 0; i < 1000; i++) { Object obj = new Object(); // Fast, lock-free (TLAB) } System.out.println(Thread.currentThread().getName() + " done"); }; // Threads allocate in parallel without contention Thread t1 = new Thread(task); Thread t2 = new Thread(task); t1.start(); t2.start(); } } class Person { String name; Person(String name) { this.name = name; } } // Object memory layout (conceptual) class ObjectLayoutDemo { public static void main(String[] args) { /* Object layout in memory: +-------------------+ | Object Header | 12-16 bytes | - Mark Word | 8 bytes (hash, age, lock) | - Class Pointer | 4-8 bytes (compressed oops) +-------------------+ | Instance Data | Variable size | - Fields | +-------------------+ | Padding | Align to 8 bytes +-------------------+ */ Person p = new Person("Alice"); // Rough memory calculation: // Header: 12 bytes // name reference: 4 bytes (compressed) // Padding: 0 bytes (12+4=16, already aligned) // Total: ~16 bytes (object itself) // + String object memory } } // String concatenation class StringConcatenationDemo { public static void main(String[] args) { // ❌ BAD: Creates many intermediate String objects String result = ""; for (int i = 0; i < 1000; i++) { result += i; // Each iteration creates new String! } // ✅ GOOD: StringBuilder (single mutable object) StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append(i); // Modifies same object } String result2 = sb.toString(); } }

5. The Comparison & Decision Layer

String Literalnew String()Use When
String poolRegular heapLiterals (pool)
SharedUniqueNeed unique (heap)
Memory-efficientMemory wastefulUsually literals

6. The "Interview Corner" (The Edge)

The "Killer" Interview Question: "How many objects are created?"

java
String s1 = "Hello"; String s2 = "Hello"; String s3 = new String("Hello");

Answer: 2 objects!

  • 1 object: "Hello" in String pool (shared by s1 and s2)
  • 1 object: new String() in regular heap (s3)
java
s1 == s2 // true (same pool object) s1 == s3 // false (s3 is different heap object) s1.equals(s3) // true (same content)

Pro-Tips:

  1. TLAB benefits:
text
Without TLAB: - All threads compete for Eden space - Synchronization overhead - Slower allocation With TLAB: - Each thread has private buffer (~1% of Eden) - Lock-free allocation - Fast path - Falls back to slow path if TLAB full
  1. String pool memory:
java
// ✅ GOOD: Pool (memory efficient) String s1 = "Hello"; String s2 = "Hello"; // Reuses s1 // ❌ BAD: Heap (memory wasteful) String s3 = new String("Hello"); // Separate object // Use new String() only when you need distinct object!

Topics Covered

Java Fundamentals

Tags

#java#programming#beginner-friendly

Last Updated

2025-02-01