
자바의 메모리 구조는 크게 메서드 영역, 스택 영역, 힙 영역 3개로 나눌 수 있다.
new 명령어를 사용하면 이 영역을 사용한다. 쉽게 이야기해서 붕 어빵 틀로부터 생성된 붕어빵이 존재하는 공간이다. 참고로 배열도 이 영역에 생성된다.메서드 영역은 프로그램을 실행하는 데 필요한 공통 데이터를 관리한다. 위 메서드 영역은 프로그램의 모든 영역에서 공유한다.
1) 클래스 정보
클래스의 실행 코드(바이트 코드), 필드, 메서드와 생성자 코드 등 모든 실행 코드가 존재한다.
2) static 정보
static 변수들을 보관
3) 런타임 상수 풀
프로그램을 실행하는데 필요한 공통 리터럴 상수를 보관한다. 예를 들어서 프로그램에"hello" 라는 리터럴 문자가 있으면 이런 문자를 공통으로 묶어서 관리한다. 이 외에도 프로그램을 효율 적으로 관리하기 위한 상수들을 관리한다.
자바 실행 시, 하나의 실행 스택이 생성된다. 각 스택 프레임은 지역 변수, 중간 연산 결과, 메서드 호출 정보 등을 포함하고 있다. 스택 영역에 쌓이는 네모 박스가 하나의 스택 프레임이다. 메서드를 호출할 때 마다 하나의 스 택 프레임이 쌓이고, 메서드가 종료되면 해당 스택 프레임이 제거된다.
객체(인스턴스)와 배열이 생성되는 영역으로 자바에서 특정 클래스로 100개의 인스턴스를 생성하면, 힙 메모리에 100개의 인스턴스가 생긴다. 각각의 인스턴스는 내부에 변수와 메서드를 가진다.
같은 클래스로부터 생성된 객체라도, 인스턴스 내부의 변수 값은 서로 다를 수 있지만, 메서드는 공통된 코드를 공유한다. 따라서 객체가 생성될 때 인스턴스 변수에는 메모리가 할당되지만, 메서드에 대한 새로운 메모리 할당은 없다. 메서드는 메서드 영역에서 공통으로 관리되고 실행된다. 정리하면 인스턴스의 메서드를 호출하면 실제로는 메서드 영역에 있는 코드를 불러서 수행한다.
특정 클래스에서 공용으로 함께 사용할 수 있는 변수를 만들고자 생성하는데, 멤버 변수에 static을 붙이게 되면 static 변수, 정적 변수, 클래스 변수라고 한다.
package memory;
public class Data3 {
String name;
static int count;
Data3(String name) {
this.name = name;
count ++;
}
}
package memory;
public class DataCountMain3 {
public static void main(String[] args) {
Data3 data1 = new Data3("A");
System.out.println("A count: " + Data3.count);
Data3 data2 = new Data3("B");
System.out.println("B count: " + Data3.count);
Data3 data3 = new Data3("C");
System.out.println("C count: " + Data3.count);
}
}
data1.count 라고 사용하는 것이 아니라 클래스에 직접 접근하듯 Data3.count 과 같이 클래스명에 .(dot)을 사용한다.인스턴스 변수: static 이 붙지 않은 멤버 변수, 예) name
static 이 붙지 않은 멤버 변수는 인스턴스를 생성해야 사용할 수 있고, 인스턴스에 소속되어 있다. 따라 서 인스턴스 변수라 한다.
인스턴스 변수는 인스턴스를 만들 때 마다 새로 만들어진다.
클래스 변수: static 이 붙은 멤버 변수, 예) count
클래스 변수, 정적 변수, static 변수등으로 부른다. 용어를 모두 사용하니 주의하자
static 이 붙은 멤버 변수는 인스턴스와 무관하게 클래스에 바로 접근해서 사용할 수 있고, 클래스 자체에 소속되어 있다. 따라서 클래스 변수라 한다.
클래스 변수는 자바 프로그램을 시작할 때 딱 1개가 만들어진다. 인스턴스와는 다르게 보통 여러곳에서 공 유하는 목적으로 사용된다.
김영한 - 실전 자바