자바는 객체지향 프로그래밍 언어이다.
절차지형적, 구조적 언어인 C언어와 비교하여 어떤 부분들이 JAVA에 녹아들었는지 살펴보자.
절차지향적이라함은, 어셈블리어의 유산인 goto를 사용하지 않는것이다. 구조적이라함은, 함수를 통해 중복되는 코드를 구조화하고, 재사용하는것을 의미한다. 위 두가지 특성은 자바의 메소드에 녹아있다.
함수와 메소드의 차이는 그저 이름이 다를 뿐이지만, 굳이 찾자면 객체안에 존재하는지 여부에 따라 볼 수 있다.
자바에선 goto와 같은 아무기능없는 예약어를 등록하여 절차지향적 특성을 지키며, 메소드를 통해 함수를 구현하며 구조적 특성을 유지했다.
JVM은 자바 언어를 실행하기 위한 가상 컴퓨터이다.
가상 컴퓨터라 함은 실체가 없으며, 프로그램으로만 존재하는걸 의미한다.
현실세계에서 프로그램은 실행되기 위해 컴파일러와, 운영체제, 하드웨어 세가지 실체가 필요하다.
가상 컴퓨터(JVM)는 하드웨어와 대응되는 프로그램이다.
JRE 운영체제와 대응되는 프로그램이다.
JDK 컴파일러와 대응되는 프로그램이다.
이제, 변수가 메모리에 어떻게 저장되며, 메소드가 어떻게 호출되고 메모리에 어떻게 변화를 일으키는지 살펴보겠다.
Java에서 메모리 사용방식을 이해하기 전에, 표준화된 메모리 사용방식을 알아본다.
프로세스는 메모리를 아래와 같은 영역으로 나누어 사용한다.
힙, 스택, 데이터, 코드
데이터 영역은 전역 변수와 정적 변수(static variable)가 저장되는 메모리 공간이다. 이 영역에 저장된 변수들은 프로그램 실행 내내 유지되며, 모든 함수와 스코프에서 접근할 수 있다.
코드 영역은 실행 파일 내의 기계어 명령어(프로그램 코드)가 저장되는 공간이다.
스택은 함수가 호출될 때 생성되는 콜 스택 프레임에 지역변수들을 저장하는 메모리 영역이다. 함수 실행 중 생성된 지역변수들은 이 프레임에 저장되며, 함수가 종료되면 해당 프레임과 함께 지역변수들도 자동으로 제거된다. 새로운 함수가 호출되면 새로운 스택 프레임이 생성되어, 해당 스코프의 지역변수들이 그 안에 저장된다.
힙은 동적으로 할당된 메모리가 저장되는 공간으로, 런타임 중에 개발자가 직접 할당 및 해제할 수 있는 영역이다.
자바에선 위에서 변형된 메모리 구조를 사용한다.
힙, 스택은 그대로 사용하나, 코드 및 데이터영역이 변경된다.
상동
상동
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
위 코드가 실행될때, Java에서의 메모리가 어떻게 사용되어지는지 살펴보자.
JRE는 .class 오브젝트 파일을 실행하라 명령받았을때, main 메소드가 존재하는지 확인한다. JRE는 프로그램 실행을 위한 사전준비에 돌입한다.JVM을 실행한다.java.lang을 스태틱 영역에 적재한다. 스태틱 영역에 적재한다.
스태틱 영역은코드 영역,데이터 영역이 합쳐진 공간이다. 클래스 파일의 모든 실행 코드는 이곳에 저장되며,정적변수또한 이곳에 저장된다.
JVM은 메소드의 {를 감지하면, 스택 영역에 Stack Frame이 할당된다. JVM은 메소드의 argument를 저장하기 위한 공간을 할당된 Stack Frame에 마련한다. JVM은 마침내, 메소드를 실행한다. JVM이 메소드의 }을 감지하면, Stack Frame을 소멸한다.JVM은 main메소드가 끝나면 종료된다. JRE또한 종료되며, 운영체제 내에서 메모리를 반환한다.java psvm이 어떻게 실행되는지 살펴봤다.
메소드가 실행될떄, JVM에 의해 스택 프레임이 생성되고, 이 내에서 변수를 생성하고 조작하며, 이후에 스택 프레임을 해제한다고 했다.
메소드내에서 분기문을 만나면 어떻게 될까?
현재 메소드 스택 프레임내에, 분기문-결과로 명명된 스택 프레임을 생성하고 분기문이 끝나면, 이를 해제한다.
자바엔 세가지 변수가 있다.
지역 변수, 인스턴스 변수, 클래스 변수
지역 변수
지역 변수는 스택 영역에 존재한다.
지역 변수는 메소드 내에서만 유지되는 변수들을 의미한다.
위에서 알아봤듯이, 모든 지역 변수는 Stack Frame내에 할당되며, Stack Frame종료시 무효하다.
인스턴스 변수
인스턴스 변수는 힙 영역에 존재한다.
GC에 의해 관리되어진다.
클래스 변수
클래스 변수는 메소드 영역에 저장된다.
클래스 변수는 클래스내에 static으로 선언된 변수를 의미한다.
JVM 종료시까지 유효하다.