자바는 메모리를 효율적으로 관리하기 위해 다양한 메모리 영역을 사용하는데, 이 중에서 Static, Heap, Stack에 대해 다뤄보려고 한다.
Static Memory는 프로그램 실행 시에 할당되고 프로그램의 라이프사이클과 함께 유지되는 데이터를 저장하는 영역이다. 즉 프로그램이 종료될 때까지 유지된다.
public class Circle {
public static final double PI = 3.14; // 클래스 변수, 상수
public static int counter = 0; // 클래스 변수
private double radius;
public Circle(double radius) {
this.radius = radius;
counter++; // counter 공유
}
public double getArea() {
return PI * radius * radius; // PI 공유
}
public static int getCounter() {
return counter; // counter 공유
}
}
public class Main {
public static void main(String[] args) {
Circle circle1 = new Circle(5.0);
System.out.println(circle1.getArea()); // 출력: 78.5
System.out.println(Circle.getCounter()); // 출력: 1
Circle circle2 = new Circle(3.0);
System.out.println(circle2.getArea()); // 출력: 28.26
System.out.println(Circle.getCounter()); // 출력: 2
}
}
Heap Memory는 동적으로 할당되는 데이터와 객체를 저장하는 영역이다. 자바에서는 new 연산자를 사용하여 객체를 생성할 때 Heap Memory에서 메모리를 할당한다.
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class Main {
public static void main(String[] args) {
Person person1 = new Person("John", 25); // 객체 생성
System.out.println(person1.getName()); // 출력: John
System.out.println(person1.getAge()); // 출력: 25
Person person2 = new Person("Jane", 30); // 객체 생성
System.out.println(person2.getName()); // 출력: Jane
System.out.println(person2.getAge()); // 출력: 30
}
}
Stack Memory는 메서드 호출 시 생성되는 지역 변수와 메서드 실행에 필요한 정보를 저장하는 영역이다. 각 스레드마다 별도의 Stack Memory가 생성되며, 메서드가 호출될 때마다 해당 메서드의 지역 변수와 매개변수, 복귀 주소 등이 저장된다.
public class Calculator {
public static int add(int a, int b) {
int sum = a + b; // 스택 프레임에 저장
return sum;
}
public static void main(String[] args) {
int num1 = 5; // 스택 프레임에 저장
int num2 = 10; // 스택 프레임에 저장
int result = add(num1, num2); // add()의 실행이 끝나면 스택 프레임 소멸
System.out.println(result); // 출력: 15
}
}