JVM이란?
자바 애플리케이션을 실행하기 위한 가상 컴퓨터. 자바 소스 코드를 컴퓨터가 이해할 수 있도록 실행시키는 해석기 역할을 수행한다. .class 파일을 읽고 해석하여 실제 실행하며 운영체제에 독립적으로 동작할 수 있게 만드는 핵심 요소이다. JVM은 자바가 범용성과 이식성을 갖추는 데 결정적 역할을 한다. 단순한 실행 도구가 아닌, 자바 철학의 중심축이라 할 수 있다.
1. 자바의 플랫폼 독립성
- 일반적인 프로그램의 실행 방식
- 프로그램은 운영체제에게 CPU, 메모리, 입출력 장치 같은 자원을 요청
- 운영체제마다 요청 방식이 다르므로, 프로그래밍 언어는 일반적으로 운영체제에 종속적이다.
- 자바의 방식
- 자바는 직접 운영체제와 소통하지 않고 JVM을 통해 간접적으로 운영체제와 상호작용한다.(운영체제마다 별도로 제작)
- 자바 프로그램 → JVM → 운영체제
- 이 덕분에 자바는 어떤 OS에서든 한 번 작성한 코드를 모든 환경에서 실행 가능하게 한다.(Write Once, Run Anywhere)

2. JVM 구조
2 - 1. 자바 실행 흐름과 JVM의 역할

- 자바 코드는 .java파일로 작성되며, 컴파일러(.javac)를 통해 .class바이트코드로 변환된다. 이후 JVM이 실행되며 아래의 단계가 진행된다.
- 클래스 로더(Class Loader) : .class 파일을 메모리에 로드
- 런타임 데이터 영역(Runtime Data Area)에 메모리 할당
- 실행 엔진(Execution Engine)이 바이트코드를 해석하고 실행
- 인터프리터(Interpreter) : 한 줄씩 실행
- JIT 컴파일러(Just-In-Time Compiler) : 반복 실행되는 코드를 통째로 기계어로 번역해 성능 향상
2 - 2. JVM 메모리 구조

| 영역 | 저장 내용 | 생명 주기 | 특징 |
| Method Area | 클래스 정보, static, final | JVM 종료 시까지 | 모든 스레드에서 공유 |
| Heap | 객체(인스턴스), 배열 | GC가 제거 전까지 | 유연하지만 상대적으로 느림 |
| Stack | 지역 변수, 참조 변수, 리턴 값 등 | 메서드 종료 시 자동 제거 | 빠르지만 제한적 메모리 |
2 - 3. Stack과 Heap의 동작 방식
- Stack : 메서드 실행을 위한 저장소
- LIFO 구조 (Last In First Out)
- 메서드 호출 시마다 스택 프레임이 위로 쌓임
- 프레임 안에는 지역 변수, 매개변수, 연산 중 발생하는 값 등을 저장
- Heap : 실제 객체 저장소
- 프로그램 실행 중 생성된 객체는 모두 Heap에 저장
- 각 참조 변수는 Stack에 존재하고, Heap의 주소를 참조
- 예시에서 Person()은 Heap에 객체를 생성
- 참조 변수 p는 Stack에 저장되며, 객체의 주소를 가리킴
Person p = new Person(); //예시
3. Garbage Collection(GC)
3 -1. Garbage Collection이란?
프로그램 실행 도중 더 이상 참조되지 않는 객체를 탐지하고 제거해 메모리를 확보하는 자동화된 메커니즘이다.
- C/C++ 등은 개발자가 수동으로 메모리 해제를 해야 하지만, 자바는 JVM이 자동으로 관리한다.
- 메모리 누수, dangling pointer 등 위험을 줄일 수 있다.
###Garbage Collection은 중요한 개념이기에 이 글이 아닌 다른 글에서 따로 다뤄볼 예정이다###
4. 메모리 누수 방지 방법(Memory Leak Prevention)
4 - 1. 메모리 누수란?
"더 이상 사용되지 않지만 여전히 참조되고 있어 GC가 수거하지 못하는 객체"를 뜻한다.
- 참조만 끊기면 GC가 수거할 수 있지만, 의도치 않게 참조가 유지되면 메모리 점유가 계속된다. 이는 OutOfMemoryError의 원인이
되기도 한다.
4 - 2. 메모리 누수가 발생하기 쉬운 상황
- 요약 정리
| 원인 구분 | 설명 | 예방 전략 |
| 컬렉션 누수 | 객체를 리스트, 맵 등에 추가만 하고 제거하지 않음 | 사용 종료 시 remove() 명시 호출 |
| static 변수 유지 | 정적(static)영역은 애플리케이션 종료 시까지 유지됨 | 캐시 전략 적용, 약한 참조 사용 |
| 리스너/콜백 해제 누락 | 이벤트 객체 등록만 하고 해제하지 않음 | removeListener(), WeakReference 사용 |
※※※ JVM은 강력한 GC를 갖고 있지만, "참조가 끊어져야 수거할 수 있다"는 원칙을 항상 기억하자!
※※※ 메모리 누수는 발견하기 어렵고, 누적되면 시스템 자원을 고갈시켜 애플리케이션의 성능 저하 또는 비정상 종료로 이어질 수 있다.
- 일상적인 코드에서도 항상 객체 참조 여부를 체크하고, 필요한 경우 해제하는 습관을 들이는 것이 중요하다.
'자바 고급(JAVA)' 카테고리의 다른 글
| 객체지향 프로그래밍의 4가지 핵심 개념 - 캡슐화(Encapsulation) (0) | 2026.05.12 |
|---|---|
| 객체지향 프로그래밍의 4가지 핵심 개념 - 상속(Inheritance) (0) | 2026.05.12 |
| 객체지향 프로그래밍의 이해 - Garbage Collection(GC) (0) | 2026.05.06 |
| 객체지향 프로그래밍의 이해 - 클래스와 객체 (0) | 2026.05.06 |
| 객체지향 프로그래밍의 이해 - 객체지향 프로그래밍이란? (0) | 2026.05.06 |