🧩 BE
home

자바의 메모리 관리

Date
2024/07/23
Category
Programming Language
Tag
Java
Detail
Java Deep
우선 기존 공부한 내용을 참고해서 JVM 내부 구조에 대해 다시 알아보기!

자바 변수의 종류

메모리 영역에 대한 설명 전에 자바에서 선언 위치에 따른 변수의 종류를 먼저 알아보자.
변수는 크게 4종류로, 선언된 위치에 따라 클래스 변수, 인스턴스 변수, 지역 변수, 매개 변수로 나뉜다.
public class Main { pubilc static void main(String[] args) { // 매개 변수 int num = 990; // 지역 변수 } } public class Counter { private int state = 0; // 인스턴스 변수 public static int gage = 100; // 클래스 변수 public int get() { return state; } }
Java
복사
변수명
선언위치
설명
클래스 변수 (class variable) (= static variable)
클래스 영역
클래스 영역에서 타입 앞에 static이 붙는 변수 객체를 공유하는 변수로 여러 객체에서 공통으로 사용하고 싶을 때 정의
인스턴스 변수 (instance variable)
클래스 영역
클래스 영역에서 static이 아닌 변수 개별적인 저장 공간으로 객체/인스턴스마다 다른값 저장 가능 * 객체/인스턴스 생성만 하고 참조 변수가 없는 경우 GC에 의해 자동 제거됨
지역 변수 (local variable)
메서드 영역
메서드 내에서 선언되고 메서드 수행이 끝나면 소멸되는 변수 초깃값을 지정한 후 사용할 수 있음
매개 변수 (parameter)
메서드 영역
메서드 호출 시 ‘전달하는 값’을 가지고 있는 인수 지역 변수처럼 선언된 곳부터 수행이 끝날 때까지 유효함
각 변수의 생성 시기는 다음과 같다.
클래스 변수 : 클래스가 메모리에 올라갈 때
인스턴스 변수 : 인스턴스가 생성되었을 때
지역 변수 / 매개 변수 : 위치하고 있는 메서드가 수행되었을 때

Method(Static) 영역

JVM이 읽어들인 클래스와 인터페이스에 대한 런타임 상수 풀, 멤버 변수(필드), 클래스 변수(Static 변수), 상수(final), 생성자(constructor)와 메서드(method) 등을 저장하는 공간
JVM이 동작해서 클래스가 로딩될 때 생성
메서드 영역에 있는 것은 어느곳에서나 접근 가능
메서드 영역의 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 존재. 그래서 static 메모리의 데이터들은 프로그램이 종료될 때까지 어디서든 사용이 가능. 그러나 static을 무분별하게 많이 사용할 경우 메모리 부족 현상이 일어날 수 있음
public class Main { public static int s = 10; public static void main(String[] args) { int a = 5; int b = 5; int result1 = a + b + Main.s; System.out.println(result1); // 20 Counter sub = new Counter(); twice(sub); int result2 = sub.get(); System.out.println(result2); // 100 } public static void twice(Counter c) { c.plus(10); c.plus(20); } } class Counter { public int state = 50; public final int count = 20; public int get() { return state + count; } public void plus(int n) { state += n; } }
Java
복사
위의 코드에서, 메서드 영역에 들어가는 코드는
Main Class
s = 10
main(String[] args)
twice(Counter c)
Counter Class
get()
plus(int n)
→ 클래스 변수(static)와 메서드는 무조건 메서드 영역에 적재된다.
→ 일반 인스턴스 변수인 Counter 클래스의 변수 statecount는 final 키워드가 붙었음에도 메서드 영역에 들어가지 않는다. (Heap에 들어감)

Stack 영역

메서드 내에서 정의하는 primitive 타입의 데이터(int, double, byte, long, boolean 등)에 해당되는 지역 변수, 매개 변수 데이터 값이 저장
메서드가 호출될 때 스택 영역에 스택 프레임이 생기고 그 안에 메서드를 호출
메서드가 호출될 때 메모리에 할당되고 종료되면 메모리에서 사라짐
Stack은 후입선출. 스코프의 범위를 벗어나면 스택 메모리에서 사라짐
위의 코드에서 psvm이라는 메인 메서드가 실행되면, 스택 영역에 스택 프레임이 쌓이고 안에 지역 변수와 매개 변수가 담기게 된다.
main 스택 프레임 (stack이므로 역순으로)
result1 = 20 (a + b + Main.s) → Main.s는 메서드 영역에 상주하기에 간단한 호출로 데이터 가져옴
b = 5
a = 5
args = null
→ 메서드의 매개변수 args와 메서드 블록 안의 지역 변수 a, b, result1 이 담아진다.

Heap 영역

Reference 타입의 데이터(객체(인스턴스), 배열 등)가 저장
단, Heap 영역에 있는 오브젝트들을 가리키는 레퍼런스 변수는 stack에 적재
이게 뭔소리??
JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역
Heap 영역은 Stack 영역과 다르게 보관되는 메모리가 호출이 끝나더라도 삭제되지 않고 유지.
자바는 자동 메모리 관리 기능을 제공하는 프로그래밍 언어 중 하나이다. 이는 개발자가 메모리 할당과 해제를 직접 관리하지 않아도 되게 해주며, 이로 인해 개발의 효율성이 크게 향상된다.
왜냐하면 자바의 가비지 컬렉션(Garbage Collection, GC) 시스템이 더 이상 사용되지 않는 객체를 자동으로 감지하고, 메모리에서 해제하기 때문이다. 이는 메모리 누수를 방지하고 애플리케이션의 안정성을 높이는 데 기여한다.