본문 바로가기
language/java

Java 객체 생성 과정과 메모리 흐름 완벽 이해하기

by 죄니안죄니 2026. 5. 26.
반응형

Java 객체 생성 과정과 메모리 흐름 완벽 이해하기

Java를 공부하다 보면 정말 많이 보게 되는 코드가 바로:

 
User user = new User();
 

입니다.

하지만 실제 JVM 내부에서는 이 한 줄이 실행될 때:

  • 클래스 로딩
  • 메모리 할당
  • 객체 생성
  • 생성자 호출
  • 참조 연결

등 매우 많은 작업이 수행됩니다.

실무에서도:

  • GC
  • 메모리 누수
  • 객체 생성 비용
  • 성능 최적화
  • Spring Bean 생성

까지 이 흐름과 깊게 연결됩니다.

이번 글에서는:

  • new 연산자 내부 동작
  • 객체 생성 과정
  • Stack / Heap 흐름
  • 생성자 호출 순서
  • 참조 연결
  • GC 대상화

까지 JVM 관점에서 깊게 정리해보겠습니다.


1. 가장 기본 코드

예제:

 
User user = new User();
 

이 코드 한 줄 내부에서 JVM은 매우 많은 일을 수행합니다.


2. 먼저 클래스 로딩 확인

객체 생성 전에 JVM은:

User.class
 

가 JVM 메모리에 존재하는지 확인합니다.

없다면:

ClassLoader 동작
 

발생.


3. ClassLoader 수행 작업

ClassLoader는:

.class 파일 읽기
↓
ByteCode 검증
↓
Method Area 적재
 

수행.


4. Method Area에 저장되는 것

저장 내용:

  • 클래스 정보
  • 메서드 정보
  • static 변수
  • 생성자 정보
  • Constant Pool

5. 객체 생성 시작

클래스 로딩 완료 후:

 
new User()
 

실행.

여기서 실제 객체 생성 시작.


6. Heap 메모리 공간 탐색

JVM은 Heap 영역에서:

빈 메모리 공간 탐색
 

수행.

즉:

객체 저장 가능한 영역 찾기
 

과정 발생.


7. Heap에 객체 메모리 할당

예를 들어:

 
class User {

    int age;
    String name;
}
 

라면 Heap에:

User 객체 공간 확보
 

수행.


8. 객체 초기화(Default Initialization)

객체 생성 직후:

모든 필드 기본값 초기화
 

발생.

예시:


타입 기본값
int 0
boolean false
reference null

9. 현재 상태

즉 생성 직후 객체는:

age = 0
name = null
 

상태.


10. 생성자(Constructor) 호출

그 다음:

 
User()
 

생성자 실행.


11. 생성자 내부 실행

예시:

 
public User() {

    this.age = 20;
}
 

실행 시:

Heap 객체 내부 값 변경
 

발생.


12. 생성자 호출 순서

상속 구조에서는 매우 중요.

예시:

 
class Parent {

    Parent() {
        System.out.println("Parent");
    }
}

class Child extends Parent {

    Child() {
        System.out.println("Child");
    }
}
 

13. 실행 결과

 
new Child();
 

결과:

Parent
Child
 

14. 왜 부모 생성자가 먼저 호출될까?

자식 객체 내부에는:

부모 영역 포함
 

되어 있기 때문.

즉:

부모 초기화
↓
자식 초기화
 

순서 필요.


15. Stack 영역 변화

예시:

 
User user = new User();
 

실행 시 Stack에는:

user 변수 생성
 

됩니다.


16. 중요한 핵심

Stack에는 실제 객체가 아니라:

참조값(reference)
 

저장됩니다.


17. 메모리 구조 그림

Stack:
user -> 0x1000

Heap:
0x1000 -> User 객체
 

즉:

  • Stack = 주소 저장
  • Heap = 실제 객체 저장

18. this는 무엇일까?

생성자 내부:

 
this.age = 20;
 

여기서:

this = 현재 Heap 객체 참조
 

입니다.

즉:

0x1000
 

같은 주소 참조.


19. 객체 생성 전체 흐름 요약

전체 흐름:

ClassLoader 확인
 ↓
Method Area 클래스 적재
 ↓
Heap 메모리 할당
 ↓
필드 기본값 초기화
 ↓
생성자 실행
 ↓
Stack 참조 연결
 

20. String 객체는 조금 특수

예시:

 
String s = "Java";
 

이건:

String Pool
 

사용 가능.

즉 동일 문자열 재사용 최적화 수행.


21. new String()은 다름

 
new String("Java")
 

실행 시:

새 Heap 객체 생성
 

발생.


22. 참조 변수 복사

예시:

 
User a = new User();

User b = a;
 

메모리:

a -> 0x1000
b -> 0x1000
 

즉:

같은 객체 참조
 

중.


23. 그래서 한쪽 수정 시 영향 발생

 
b.name = "Kim";
 

하면:

 
a.name
 

도 변경됨.

왜냐하면:

같은 Heap 객체
 

이기 때문.


24. 메서드 호출 시 객체 전달

예시:

 
test(user);
 

실제로는:

참조값 복사 전달
 

입니다.

즉 객체 자체 복사 아님.


25. 그래서 Side Effect 발생 가능

메서드 내부:

 
user.name = "Lee";
 

하면 외부 객체도 변경됨.


26. 객체 생성 비용이 존재하는 이유

 
new Object()
 

실행 시 실제로:

  • Heap 탐색
  • 메모리 할당
  • 객체 초기화
  • 생성자 호출

발생.

즉 비용 존재.


27. 그래서 객체 생성 과다 시 문제 발생

예시:

 
while(true) {
    new Object();
}
 

결과:

Heap 과부하
↓
GC 증가
↓
성능 저하
 

가능.


28. GC(Garbage Collector)와 객체

객체는:

참조 끊기면
 

GC 대상 가능.


29. 예시

 
user = null;
 

더 이상 참조 없으면:

GC 수거 가능
 

상태.


30. 메서드 종료 후

예시:

 
void test() {

    User user = new User();
}
 

메서드 종료 시:

Stack Frame 제거
 

즉:

user 참조 제거
 

발생.

Heap 객체는:

GC 대상 가능
 

될 수 있음.


31. escape analysis와 연결

Escape Analysis 는:

객체가 메서드 밖으로 나가는가 분석

하는 JVM 최적화 기술.


32. JVM 최적화 가능

객체가 외부로 escape하지 않으면:

Heap 생성 생략
 

가능할 수도 있음.

(JIT 최적화)


33. 객체 생성과 Thread-safe

가변 객체는:

동시 접근 문제
 

가능.

그래서:

  • immutable 객체
  • ThreadLocal
  • synchronized

등과 연결됨.


34. 실무에서 자주 하는 실수

1) 참조 복사와 객체 복사 혼동

 
User b = a;
 

객체 복사 아님.


2) 객체 생성 비용 무시

대량 생성 시 GC 부담 증가 가능.


3) 메서드 호출 시 객체 전체 복사된다고 착각

실제로는:

reference 전달
 

입니다.


35. 객체 생성 흐름 핵심 요약

new 실행
 ↓
Heap 메모리 할당
 ↓
필드 기본값 초기화
 ↓
생성자 실행
 ↓
Stack 참조 연결
 

36. 가장 중요한 핵심 한 줄

Stack에는 참조값
Heap에는 실제 객체
 

입니다.

Java 메모리 구조의 핵심.


37. 실무에서 객체 생성 흐름 이해가 중요한 이유

대표 사례:


문제 연결
GC 과부하 객체 과다 생성
Memory Leak 참조 유지
성능 저하 객체 생성 비용
OOM Heap 부족

38. 정리

Java 객체 생성은 단순히:

 
new User()
 

한 줄로 끝나는 작업이 아닙니다.

실제로는:

  • 클래스 로딩
  • Heap 메모리 할당
  • 생성자 실행
  • 참조 연결
  • GC 관리

까지 매우 많은 JVM 내부 작업이 수행됩니다.

특히 실무에서는:

  • Stack vs Heap
  • reference 구조
  • 객체 생성 비용
  • GC 대상 조건

을 정확히 이해하는 것이 매우 중요합니다.

다음 글에서는:

참조 타입(reference type)과 객체 참조

를 shallow copy / deep copy, call by value, Java reference 구조까지 포함해서 깊게 정리해보겠습니다.

반응형

댓글