java 변수 종류와 이게 JVM 메모리 상에 어떻게 다르게 저장되는지 정리 .
기본 공부하려고 자바의 정석 조금씩 읽다가 정리한당.
1. 클래스 변수, 인스턴스변수, 지역 변수
이 셋을 구분 짓는건 변수 선언된 위치이다.
- 클래스 변수: 클래스 영역에서 선언되었으며 앞에 static 붙어있음. 모든 인스턴스 (클래스를 통해 객체화된 인스턴스들)이 공통된 변수를 공유하게 된다.
클래스의 모든 인스턴스들이 공통된 값을 가져야하는 경우 이를 사용하면 된다.
클래스가 메모리에 올라갈 때 메서드 영역에 생성된다. - 인스턴스 변수: 클래스 영역에서 선언됨. 인스턴스를 생성할 때 만들어진다. 즉 사용하려면 먼저 인스턴스를 생성해야한다.
인스턴스마다 각자 고유한 값을 가져야한다면 인스턴스 변수로 만든다. - 지역 변수: 메서드 내에 선언되어 메서드 내에서만 사용가능하며 종료되면 소멸되어 사용 불가능하다.
2. JVM 메모리 구조
메소드 영역
JVM 이 클래스 파일 읽어 클래스에 대한 정보 저장하는 곳이다.
힙 영역
new 키워드로 생성된 인스턴스가 생성되는 장소. 메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거한다.
스택
메서드가 호출되면 이를 위한 메모리 할당된다. 이 메서드를 실행하는데 필요한 지역 변수등 임시 데이터를 저장하는데 쓰인다. 메서드가 종료되면 공간이 반환되어 비어진다.
이름에서 알 수 있듯이 메모리 공간은 메서드 호출 순대로 차곡 차곡 할당되어 첫번째 메소드가 안 끝낫는데 두번째 메소드가 호출된다면 두번째 메소드부터 수행된다. (LIFO)
메소드 별로 저장공간은 구분된다. 잘못된 재귀 호출로 무한 루프에 빠지면 스택이 계속 쌓여서 스택오버플로우 에러가 난다.
PC Register (PC 레지스터)
쓰레드 생성될 때마다 생성됨. 현제 쓰레드가 실행되는 부분의 주소 저장한다.
3. 클래스 메소드에서 인스턴스 변수 호출 못하는 이유
클래스 읽어올 때부터 메소드 영역에 클래스 변수, 메소드는 존재하지만 인스턴스 변수는 아직 인스턴스 생성 안되어 존재하지 않을 수 있음.
따라서 클래스 멤버가 인스턴스 멤버 참조 또는 호출하고자 하는 경우는 인스턴스 생성해야한다.