Written by
Poogle
on
on
자바 기초 - 개발 환경
Java의 특징
1. 운영 체제에 독립적
- JVM(Java Virtual Machine)
- 자바 응용 프로그램은 JVM 하고만 통신
- 자바로 작성된 프로그램은 OS에 독립적이지만 JVM은 OS에 종속적
- 바이너리 코드를 읽고 -> 검증 후 -> 실행
- JVM을 거쳐야 하고, 하드웨어에 맞게 완전히 컴파일 된 상태가 아니고 실행 시에 해석 -> 속도 느림
- ⏩ 바이트코드(컴파일된 자바 코드)를 하드웨어의 기계어로 바로 변환해주는 JIT 컴파일러와 향상된 최적화 기술로 많이 빨라짐
JIT(Just In Time)
- 런타임에 인터프리터 방식으로 동작하는 Java의 한계를 보완
- cf.) 컴파일 방식: 소스코드를 한꺼번에 기계어로 변환
- 인터프리터 방식: 소스 코드를 런타임 시에 한 줄씩 읽어가면서 변환
- 자주 실행되는 코드블록, 메서드를 모니터링해서 네이티브 코드로 컴파일
- 별도의 쓰레드에서 실행
2. 객체 지향 언어
- 상속, 캡슐화, 다형성 적용된 순수 객체지향언어
3. 자동 메모리 관리 w.Garbage Collection
- 프로그램 실행 시 Garbage Collector가 자동적으로 메모리 관리
4. 네트워크와 분산처리 지원
5. 멀티쓰레드 지원
- 여러 쓰레드에 대한 스케쥴링을 자바 인터프리터가 담당
6. 동적 로딩(Dynamaic Loading) 지원
- 실행 시에 모든 클래스가 로딩되지 않고 필요한 시점에 클래스를 로딩하여 사용할 수 있음
- 일부 클래스가 변경되어도 전체 애플리케이션을 다시 컴파일하지 않아도 됨
JDK와 JRE
- JDK(Java Development Kit)
- 자바를 개발하기 위해 만들어놓은 tool
- JRE + 개발을 위해 필요한 도구들
- JDK를 설치하면 JVM, JRE 모두 설치됨
- JRE(Java Runtime environment)
- 자바 실행환경
- 코딩한 것을 실행, 실행의 목적지는 CPU
- JVM + 라이브러리
- 개발 관련 도구는 포함하지 않음 -> JDK
컴파일과 실행
class Hello {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
- JDK로 바이트 코드 생성 -> JRE 사용해서 바이트 코드를 실행
컴파일
- Java 코드는 컴파일 과정을 거쳐야 JVM에서 실행
- 컴파일 된 코드: Java Byte code
- 바이트코드: JVM이 읽어서 기계어로 해석할 수 있는 코드
javac Hello.java
실행
java <package>.<classname>
- -cp 옵션으로 classpath 지정, classname 뒤에 매개변수 전달 가능
javac
는 파일을 컴파일,java
는 패키지에 존재하는 클래스를 실행- 클래스 로드가 프로그램의 실행에 필요한 클래스(*.class파일)을 로드
- 클래스 파일을 검사 (클래스는 main 메서드가 호출되기 전 초기화 됨)
- 지정된 클래스에서 main을 호출(main 메서드)
JVM의 구성 요소
- 클래스 로더(Class Loader)
- 런타임 데이터 영역(Runtime Data Area)
- 실행 엔진(Execution Engine)
- JNI
- Native Method Library
클래스 로더 Class Loader
- 런타임 시점에 클래스 파일(.class)에서 바이트코드를 읽어들이고 메모리에 저장
- 동적 로딩 -> 필요한 부분만 로딩
Runtime Data Area
JVM이 프로그램을 수행하기 위해 OS로부터 별도로 할당받은 메모리 공간
- Method 영역: 스레드 간 공유, 클래스 레벨(클래스명, 부모 클래스명 인터페이스, 메소드, 필드, static 변수 등)의 정보 저장
- Heap 영역: 스레드 간 공유, GC의 대상, 클래스를 통해 인스턴스를 생성하면 힙에 저장됨, (객체, 배열 저장)
- JVM Stack 영역: 스레드 마다 생성, 메서드에 관련된 정보가 스택 프레임의 형태로 저장, 메서드 호출이 정상 완료 or 예외 던져지면 스택 프레임은 스택에서 빠지면서 소멸
- PC Register: 스레드 마다 생성, 자바 메서드에 대한 위치만 기록, 연산을 위해 필요한 피연산자를 임시로 저장
- Native Method Stack: 스레드 마다 생성, native로 작성된 메서드 정보 저장
Exection Engine
- 런타임 데이터 영역에 할당된 Java 바이트 코드를 읽어서 기계어로 번역해 실행하는 영역
1. Interpreter
- 바이트 코드 한 줄씩 실행
2. JIT Compiler
- 인터프리터 효율을 높임, 반복되는 코드를 발견하면 모두 네이티브 코드로 바꿔둠
3. Garbage Collecter
- 더이상 참조되지 않는 객체를 모아서 저장