Java vs Python: 변수와 객체의 생존 주기 완전 정리

david1-p·2025년 7월 5일

CS 지식 창고

목록 보기
8/25

변수는 이름표, 객체는 실제 물건이다.”
스코프(scope)와 객체(object)를 분리해서 이해하면 메모리 관리가 보인다.

목차

  1. 왜 이 글을 썼나
  2. Java: 변수별 수명 ― 정확히 어디서 틀리기 쉬운가?
  3. Python(CPython): 객체가 사라지는 두 단계
  4. 실습 - CPython에서 객체 소멸 로그 찍어보기
  5. 한눈에 보기!
  6. 정리 & 기억할 키워드

왜 이 글을 썼나

“지역변수가 끝나면 객체도 끝난다?”
“불변 객체는 한 번 만들면 프로그램 종료까지 남는다?”

프로그래밍 Q&A에서 꾸준히 오해가 반복되는 주제다.
여기에 Java 와 Python(CPython) 을 나란히 두고 객체와 변수의 생존 주기를 정리했다.


Java: 변수별 수명 ― 정확히 어디서 틀리기 쉬운가?

구분저장 위치살아 있는 조건흔한 오해
클래스 변수(static field)메서드영역(HotSpot 기준)Class 객체가 ClassLoader에 탑재되는 동안(JVM 종료까지 남는 경우가 많음)“메서드(콜스택)가 끝나면 사라진다”
인스턴스 변수힙(Heap)해당 객체에 강한 참조가 1개 이상“메서드 끝나면 사라진다”
지역 변수스택(Stack Frame)메서드 실행 중여기서만 대체로 맞음 — 다만 참조 변수가 가리키던 객체는 다른 곳에서 참조 중이면 생존

Point!
변수와 객체를 분리해서 보자.
스택에 있던 참조 변수가 사라져도, 힙에 있던 객체는 여전히 살아 있을 수 있다.


Python(CPython): 객체가 사라지는 두 단계

1. 참조 카운팅

  • 모든 객체에 refcount 저장
  • refcount → 0 되는 즉시 메모리 반환

2. 세대별 순환-GC

  • 서로 물고 있는 순환 참조는 refcount가 0이 되지 않음
  • 주기적으로 세대(0, 1, 2)를 스캔해 순환 그래프 탐색 후 회수
스코프 위치예시언제 사라질까?
지역 스코프함수 안 obj함수 리턴 → 참조 0 → 즉시 free
인스턴스/클래스 속성self.attr, Cls.attr속성을 지닌 객체가 참조되는 한
모듈 전역config = {...}모듈이 sys.modules에 남아 있는 한 (보통 인터프리터 종료까지)
인터닝 상수0, "", TrueCPython 내부 캐시에 보존, 인터프리터 종료 시 해제

“불변 == 영구”가 아니다!
작은 정수·짧은 문자열이 우연히 오래 남는 건 인터닝 캐시 덕분이다.
참조가 0이면 불변 객체라도 당연히 소멸한다.


실습 – CPython에서 객체 소멸 로그 찍어보기

import gc

class Demo:
    def __init__(self, name): self.name = name
    def __del__(self):
        print(f"[GC] {self.name} collected")

def make():            # 지역 스코프
    a = Demo("temp")   # refcount = 1
    b = a              # refcount = 2
    print("함수 끝…")

make()                 # a, b 모두 스코프 밖 → refcount 0
gc.collect()           # 순환 참조 없지만, 강제로 GC

예상 출력

함수 끝…
[GC] temp collected
  • a, b 참조가 동시에 사라져 refcount → 0
  • 순환 참조가 있었다면 gc.collect() 호출 시점까지 남을 수 있다.

한눈에 보기!

항목JavaPython (CPython)
메모리 관리Tracing GC (Mark-Sweep, G1 등)참조 카운팅 + 순환-GC
“즉시 소멸” 가능?❌ (GC 싸이클 기다림)✅ (refcount 0)
순환 참조 처리기본 GC가 해결별도 순환-GC 패스
불변 객체 최적화String 상수 풀, class constant pool작은 int·짧은 str 인터닝
finalize / delfinalize() (Java 9 이후 deprecated)del() (주의해서 사용)

정리 & 기억할 키워드

  • 변수(scope)와 객체(lifetime)는 별개!
  • Java : ClassLoader + GC 가 객체 생명을 결정
  • CPython : refcount 0 → 즉시 free, 순환 참조는 generational GC
  • “불변 == 영구” 아님. 캐싱(Interning) 때문에 오래 살아 보일 뿐
  • 객체 소멸이 필요하면 컨텍스트 매니저(Python), try-with-resources(Java) 등을 우선 고려
profile
DONE IS BETTER THAN PERFECT.

0개의 댓글