Object Creation & Memory
Object creation and memory management explain how Java creates objects, where they are stored, and how references work at runtime. This topic is crucial for debugging, performance, interviews, and understanding JVM internals.
What Happens When an Object Is Created?
Student s = new Student();
Step-by-Step Execution Flow
-
Class Loading
- JVM loads Student.class into memory (if not already loaded)
- Class metadata stored in Method Area / Metaspace
-
Memory Allocation
- Memory allocated in the Heap for the object
- Space created for all instance variables
-
Default Initialization
- Instance variables get default values
- int → 0
- boolean → false
- Object → null
-
Constructor Execution
- Constructor initializes instance variables with actual values
-
Reference Assignment
- Reference variable s (stored in stack) points to heap object
Java Memory Areas (High-Value Interview Topic)
1. Stack Memory
- Stores local variables, method calls, and references
- Memory is method-scoped
- Automatically freed after method execution
Student s; // reference stored in stack
2. Heap Memory
- Stores objects and instance variables
- Shared across threads
- Managed by Garbage Collector
new Student(); // object stored in heap
3. Method Area / Metaspace
- Stores:
- Class structure
- Method bytecode
- Static variables
- Runtime constant pool
Visual Representation (Conceptual)
Stack
-----------------
s -----> Heap
-----------------
Student Object
name = "John"
age = 20
Object vs Reference (Very Important)
Student s1 = new Student();
Student s2 = s1;
- Only one object created in heap
- s1 and s2 both point to same object
- Changes via one reference affect the other
Multiple Objects Creation
Student s1 = new Student();
Student s2 = new Student();
- Two separate objects in heap
- Each has its own instance variables
Anonymous Objects
new Student().display();
- No reference variable
- Used for one-time use
- Eligible for garbage collection immediately after use
Static vs Instance Memory Allocation
class Test {
static int x = 10;
int y = 20;
}
| Member Type | Memory Location | Shared |
|---|---|---|
| Static variable | Method Area | Yes |
| Instance variable | Heap | No |
| Local variable | Stack | No |
Garbage Collection (Brief Intro)
- Objects with no references become eligible for GC
- GC automatically frees heap memory
- Programmer cannot explicitly delete objects
s = null; // object eligible for GC
Common Memory Scenarios (Interview-Oriented)
Case 1: Reference Reassignment
Student s = new Student();
s = new Student();
- First object becomes eligible for GC
- Second object is now referenced
Case 2: Reference as Method Parameter
void change(Student s) {
s.name = "Alex";
}
- Copy of reference passed
- Object content changes
- Still call by value
Common Beginner Mistakes
- Confusing reference with object
- Thinking reference stores object data
- Forgetting heap vs stack separation
- Assuming GC runs immediately
- Creating unnecessary objects
Interview-Ready Answers
Short Answer
Object creation in Java involves allocating memory in the heap and storing the reference in the stack.
Detailed Answer
When an object is created in Java, the class is loaded, memory is allocated in the heap, instance variables are initialized, and the constructor is executed. A reference to the object is stored in stack memory. Java manages memory using stack, heap, and method area, with garbage collection handling unused objects.
Object Creation & Memory Examples
1. Object Creation – Heap vs Stack
class Demo {
int x;
}
class Test {
public static void main(String[] args) {
Demo d = new Demo();
d.x = 10;
}
}
Explanation
- d → reference stored in stack
- new Demo() → object stored in heap
2. Multiple Objects → Separate Heap Memory
class Demo {
int x;
}
class Test {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
d1.x = 10;
d2.x = 20;
System.out.println(d1.x);
System.out.println(d2.x);
}
}
Explanation
- Each object has its own heap memory
- Output:
10
20
3. Multiple References → Single Object
class Demo {
int x;
}
class Test {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = d1;
d2.x = 50;
System.out.println(d1.x);
}
}
Explanation
- d1 and d2 point to same heap object
- Output: 50
4. Object Becomes Eligible for Garbage Collection
class Demo {
int x;
}
class Test {
public static void main(String[] args) {
Demo d = new Demo();
d = null;
}
}
Explanation
- Object has no reference
- Eligible for GC (not immediately destroyed)
5. Reassigning Reference → Old Object Eligible for GC
class Demo {
int x;
}
class Test {
public static void main(String[] args) {
Demo d = new Demo(); // Object-1
d = new Demo(); // Object-2
}
}
Explanation
- Object-1 has no reference → GC eligible
- Object-2 still alive
6. Object Created Inside Method
class Demo {
int x;
}
class Test {
static void create() {
Demo d = new Demo();
d.x = 10;
}
public static void main(String[] args) {
create();
}
}
Explanation
- Object created in heap
- Reference lost after method ends → GC eligible
7. Object Returned From Method
class Demo {
int x;
}
class Test {
static Demo create() {
Demo d = new Demo();
d.x = 100;
return d;
}
public static void main(String[] args) {
Demo ref = create();
System.out.println(ref.x);
}
}
Explanation
- Reference returned keeps object alive
- Output: 100
8. Object Passed as Method Parameter
class Demo {
int x;
}
class Test {
static void update(Demo d) {
d.x = 30;
}
public static void main(String[] args) {
Demo d = new Demo();
update(d);
System.out.println(d.x);
}
}
Explanation
- Reference copy passed
- Same heap object modified
- Output: 30
9. Reassigning Parameter Reference
class Demo {
int x;
}
class Test {
static void update(Demo d) {
d = new Demo();
d.x = 99;
}
public static void main(String[] args) {
Demo d = new Demo();
d.x = 10;
update(d);
System.out.println(d.x);
}
}
Explanation
- Reassignment affects local reference only
- Output: 10
10. Object Array – Memory Behavior
class Demo {
int x;
}
class Test {
public static void main(String[] args) {
Demo[] arr = new Demo[2];
arr[0] = new Demo();
arr[1] = new Demo();
arr[0].x = 1;
arr[1].x = 2;
System.out.println(arr[0].x + " " + arr[1].x);
}
}
Explanation
- Array holds references in heap
- Each element points to object
- Output: 1 2
11. null Reference and Memory
class Demo {
int x;
}
class Test {
public static void main(String[] args) {
Demo d = null;
// d.x = 10; // NullPointerException
}
}
Explanation
- null → no heap object
- Dereferencing causes exception
12. Object Creation Using Constructor Chain
class Demo {
Demo() {
this(10);
}
Demo(int x) {
System.out.println(x);
}
public static void main(String[] args) {
new Demo();
}
}
Explanation
- Single object, multiple constructor calls
- Output: 10
13. Static Members Stored Separately
class Demo {
static int a = 10;
int b = 20;
}
class Test {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
System.out.println(d1.b);
System.out.println(d2.b);
System.out.println(Demo.a);
}
}
Explanation
- a → method area
- b → per-object heap
- Output:
20
20
10
14. Static Block Execution (Class Loading)
class Demo {
static {
System.out.println("Class Loaded");
}
public static void main(String[] args) {
new Demo();
new Demo();
}
}
Explanation
- Static block runs once
- Output:
Class Loaded
15. Instance Block Execution (Per Object)
class Demo {
{
System.out.println("Instance Block");
}
Demo() {
System.out.println("Constructor");
}
public static void main(String[] args) {
new Demo();
new Demo();
}
}
Explanation
- Runs for every object
- Output:
Instance Block
Constructor
Instance Block
Constructor
16. String Literal vs new Object (Memory)
class Test {
public static void main(String[] args) {
String s1 = "Java";
String s2 = new String("Java");
System.out.println(s1 == s2);
}
}
Explanation
- s1 → String Pool
- s2 → Heap
- Output: false
17. Interned String Reference
class Test {
public static void main(String[] args) {
String s1 = "Java";
String s2 = new String("Java").intern();
System.out.println(s1 == s2);
}
}
Explanation
- Both refer to pool
- Output: true
18. Object Life Cycle (Simplified)
class Demo {
Demo() {
System.out.println("Created");
}
}
class Test {
public static void main(String[] args) {
Demo d = new Demo();
d = null;
System.out.println("Eligible for GC");
}
}
Explanation
- Creation → usage → GC eligible
- Output:
Created
Eligible for GC
19. Nested Object Creation
class Engine {}
class Car {
Engine e = new Engine();
}
class Test {
public static void main(String[] args) {
Car c = new Car();
}
}
Explanation
- Creating one object can create others
- All stored in heap
20. Interview Summary – Object Creation & Memory
class Demo {
int x;
}
class Test {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = d1;
d2.x = 40;
System.out.println(d1.x);
}
}
Explanation
- Reference copy, not object copy
- Output: 40
Key Takeaway
Objects live in the heap. References live in the stack. Classes live in the method area. Understanding object creation and memory flow is essential for efficient coding, debugging, and JVM-level clarity.