이번 장에서는 자바에 관한 기본 개념을 소개하고 있다.
자바 기본 개념
JDK, JRE, JVM
- JDK (Java Development Kit): 자바 개발 도구, 자바 소스 코드를 컴파일하는
javac.exe
를 포함, JDK는 JRE를 포함 - JRE (Java Runtime Environment): 자바 실행 환경, 자바 프로그램을 실행하는
java.exe
를 포함, JRE는 JVM을 포함 - JVM (Java Virtual Machine): 자바 가상 머신, 각 플랫폼에 맞게 자바 프로그램을 구동
Write Once, Run Anywhere (WORA)
- 자바 특징 중 하나, 자바 프로그램은 한 번 작성하면 어떤 플랫폼에서도 실행할 수 있다.
## 자바 메모리 구조 1. 프로그램이 메모리를 사용하는 방식 : 코드 실행 영역/데이터 저장 영역 2. 객체 지향 프로그램에서는 데이터 저장 영역을 세 개의 영역으로 분할 : 스태틱(Static)/스택(Stack),힙(Heap) - 이러한 구조를 앞으로 책에서는 T 메모리 구조라 명명
T 메모리 구조
- Static 영역(=Method, Class 영역)
- 클래스, Static 변수 및 메서드, 상수(final), 생성자, 메서드 정보 등을 저장
- 프로그램 시작 시 로딩, 종료될 때 까지 유지 (클래스 파일의 바이트 코드가 로드됨)
- Stack 영역
- 메서드 호출 시 생성되는 스택 프레임 저장
- 지역 변수(Primitive 타입의 데이터)와 매개 변수들 관리
- 메서드가 종료되면 해당 스택 프레임은 소멸
- Stack은 후입선출(LIFO, Last-In-First-Out) 특성을 가지고 있고, 스코프(Scope) 범위를 벗어나면 스택 메모리에서 소멸됨
- Heap 영역
- 객체와 인스턴스 변수(Referency Type) 저장
- GC(Garbage Collection)에 의해 메모리 관리가 이루어짐 (그 전까지는 호출이 끝나도 메모리에 남아 있음)
- (이후 3장에서 자세히 다룬다)
T 메모리 실행 과정
- 프로그램 시작
- JRE가 먼저 프로그램 안에
main()
메서드가 있는 지 확인 이후 JVM 기동 java.lang
패키지 및 import 된 클래스 static 영역에 로딩
- JRE가 먼저 프로그램 안에
main()
메서드 실행main()
메서드의 스택 프레임 생성- 지역 변수와 매개변수 공간 할당
- 메서드 호출
- 메서드 호출 시 새로운 스택 프레임이 생성되며, 호출된 메서드의 지역 변수과 반환값 공간이 할당
- 값 전달(Call by Value) 방식으로 매개변수를 복사하여 전달
- 메서드가 종료되면 스택 프레임 소멸
- 객체 생성
- Heap 영역에 객체 생성
- 객체 참조 변수는 스택 영역에 저장
- 프로그램 종료
main
메서드가 종료되면 JVM도 종료- 모든 메모리 할당 해제
스택 프레임(Stack Frame)
- 메서드가 호출될 때 생성되는 메모리 저장 공간 (Stack 영역에 위치)
- 현재 실행중인 메서드 상태 정보를 저장 (지역변수, 매개변수, 리턴 주소 등...)
- 메서드가 종료되면 해당 스택 프레임은 소멸
## 전역 변수와 멀티 스레드
- 전역 변수 사용의 문제점
- 전역 변수는 어디에서나 접근이 가능하나, 값의 변경 추적이 어렵고 코드 유지보수를 어렵게 할 수 있다.
- 멀티스레드 환경에서는 전역 변수 사용 시 데이터 충돌(동시성 문제)가 발생할 수 있다.+
- 멀티스레드와 멀티프로세스 (cf. 운영체제)
- 멀티스레드 : 하나의 메모리를 공유하며 스택 영역만 분할하여 사용
- 멀티프로세스 : 각 프로세스가 독립적인 메모리 공간을 가짐
Cf.
- Virtual Thread (경량화된 스레드)
- 최근 JDK 21부터 도입되어 기존 멀티스레드의 복잡성을 줄이고 성능을 향상시키고자 함
- 전통적인 스레드보다 더 많은 수의 스레드를 효율적으로 관리할 수 있게 함
## 절차적/구조적 프로그래밍의 유산 1. **goto 문** (쓰지마라) - 자바에서는 `goto`문을 사용할 수 없도록 설계 - 프로그램의 흐름을 복잡하게 만들 수 있기 때문 (스파케티 코드로 인해 유지보수가 어려워짐) 2. **함수(Function)/메서드(Method)** - 함수를 사용하여 코드를 모듈화하고 중복을 줄임 - 둘은 같은 의미 (객체지향 진영에서 차별화를 위해 다르게 명명되었을 뿐) - 차이점이 있다면 객체지향에서는 클래스 내에서만 정의 가능 - 전역 변수보다는 지역 변수를 쓰자 3. **제어문 (if, for 등)**
Cf.
- Kotlin에서는
main()
함수는 클래스 외부에서 정의가 가능하다. - Java도 JDK 21의 JEP 445라는 Preview 스펙으로 클래스 작성을 생략할 수 있다. (디컴파일 하게 되면 클래스명이 파일명으로 되어 있다.)
근본적으로는 클래스 내 정의되어 있지만 코드를 짤 때 생략하게 될 지도...?
IntelliJ에서 다음과 같이 오류가 나타다면 Alt + Enter로 옵션 적용