1. 메서드 영역
2. 스택 영역
3. 힙 영역
자바의 Memory Structure는 크게 세 가지로 나뉜다. 메서드 영역은 프로그램을 실행하기 위한 공통 데이터를 관리한다. 공통성에 의거하여 추론해보면 클래스 정보, static영역, 런타임 상수 풀, 메서드 정보 등이 저장된다.
예시
하나의 클래스로 부터 여러 인스턴스가 생성되었다면 해당 인스턴스들은 동일한 메서드를 실행할 수 있다. 이때 각각의 인스턴스마다의 메서드를 따로 저장하는 것이 아니라 메서드 영역에서 보관하여 공통으로 관리한다. 그리고 인스턴스가 메서드 호출시 메서드 영역의 메서드를 불러서 수행한다.
스택 영역에는 여러 스택 프레임이 쌓인다. 이러한 스택 프레임 안에는 지역 변수, 중간 연산 결과, 메서드 호출 정보등이 담긴다. 스택 프레임은 메서드의 종료시점에 따라 Pop된다.
힙 영역은 객체와 배열이 생성되는 영역이다. GC(가비지 컬렉션)또한 이곳에서 이루어진다. new 키워드로 생성된 객체는 힙에 할당된다.
package access.memory;
public class JavaMemoryMain1 {
public static void main(String[] args) {
System.out.println("main start");
method1(10);
System.out.println("main end");
}
static void method1(int m1) {
System.out.println("method1 start");
int cal = m1 * 2;
method2(cal);
System.out.println("method1 end");
}
static void method2(int m2) {
System.out.println("method2 start");
Data item = new Data();
System.out.println("method2 end");
}
}
class Data {
int x;
}

static 변수는 정적 변수라고 한다. static이 붙은 멤버 변수는 인스턴스 영역에 생성되지 않으며, 메서드 영역에서 생성된다. 그 뜻은 즉 여러 인스턴스가 공통되게 사용가능하다는 것이다. 만약 인스턴스가 몇 개 생성되었는 지 알고 싶을 때, 우리는 static을 활용 가능하다.
// Class
package static1;
public class User {
private static int userCount;
private String name;
User (String name) {
this.name = name;
this.userCount++;
}
public static void getUser() {
System.out.println(userCount);
}
}
// main
package static1;
public class UserMain1 {
public static void main(String[] args) {
User user1 = new User("Alli");
User user2 = new User("Kane");
User user3 = new User("Mason");
User user4 = new User("Veltonghen");
User user5 = new User("Bale");
User.getUser();
}
}
5개의 유저 인스턴스를 생성했다. 만약 N개의 유저 인스턴스를 생성하고 N개가 무엇인지 알려면, 배열에 생성된 모든 인스턴스를 넣고 .length를 찍거나 숫자를 세주는 Counter클래스 같은 것을 만들 수도 있겠다.
하지만 이러한 방법들은 해결을 위해 클래스 외부에서 무언가(Counter 클래스 or 배열 생성)를 들여오는 방법이다.
위의 코드에서 user의 수를 계산해주는 getUser() 메서드와 count 필드가 static으로 선언되어있다. 이 두개는 모두 클래스 아래에서의 기능이다. 실제로 main에서 인스턴스에 점을 찍는 것이 아닌 클래스에 바로 점을 찍어 getUser()를 실행한다. 그리고 getUser는 클래스의 static 변수인 count를 반환한다.
실제로 count는 User가 생성될 때 마다 ++연산이 이루어진다. 만약 static을 주지 않았다면 count는 모든 인스턴스 내에 각각이 생성되어 count는 모두 1이었을 것이다.
인스턴스 변수 : static이 붙지 않음. 인스턴스에 소속되어 있음, 인스턴스 생성 때 마다 새로 만들어짐.클래스 변수 : 정적변수, static변수라고도 불림, 인스턴스와 무관하게 클래스에 바로 접근해서 사용가능, 클래스 자체에 소속되어 있음. 클래스 변수는 자바 실행시 딱 1개만 만들어짐. 여러곳에서 공유할 목적으로 사용 됨.클래스 변수가 정적 이라는 이유
클래스 변수는 클래스가 JVM에 로딩되는 시점부터 JVM종료까지 생명주기가 이어진다.
멤버 변수의 종류와 마찬가지로
인스턴스 메서드 : static이 붙지 않음. 인스턴스에 소속되어 있음, 인스턴스 생성 때 마다 새로 만들어짐.클래스 메서드 : 정적 메서드 라고도 불림, 인스턴스와 무관하게 클래스에 바로 접근해서 사용가능, 클래스 자체에 소속되어 있음. static 메서드는 static으로 선언된 정적 메서드나 정적 변수만을 사용할 수 있다. 생각해보면 당연한 것이 개별로 만들어진 많은 인스턴스 변수를 다루는 것은 말이 안되긴 한다.
public static void main()
이때까지 배운 개념으로public static void main()을 이해할 수 있다. 클래스 안에서public static void main()을 작성하고 코드를 실행하면public static void main()안에 작성된 것들을 JVM이 쭉 읽어 나간다. JVM은 코드 실행시 main메서드를 찾는다. 이 메서드는 항상 public static으로 선언되어야 한다. 어디서든 접근 가능해야 하며, JVM에 의해 인스턴스화 되면 안되기 때문이다.