[자바기초] 자바의 개요
자바언어의 탄생과 발전
자바의 탄생과 발전
(1) 자바의 탄생 (1991년)
• 그린 프로젝트(Green Project)에서 시작
• Sun Microsystems의 제임스 고슬링(James Gosling) 주도
• 가전제품용 소프트웨어 개발을 목적으로 연구 시작
(2) 자바(Java) 공개 (1995년)
• 1995년 ‘Java’ 공식 발표
• 최초의 이름: 오크(OAK) → 이후 자바(Java)로 개명
• 공개 당시 웹 브라우저 Netscape에서 실행
(3) 자바의 발전
• 1995년 인터넷과 웹의 발전과 함께 주목받기 시작
• 2009년 Sun Microsystems가 오라클(Oracle)에 인수
• 현재까지 광범위한 분야(웹, 모바일, 서버, IoT)에서 사용
자바의 개발 목적
(1) C 언어의 포인터(pointer) 문제 해결
(2) 플랫폼 호환성 문제 해결
• 기존 언어는 PC, 유닉스, 메인프레임 간 호환성이 부족
• 소스를 다시 컴파일하거나 프로그램을 재작성해야 함
(3) 플랫폼 독립적인 언어 개발
• 모든 플랫폼에서 호환성을 갖는 프로그래밍 언어 필요
• 특히 네트워크, 웹에 최적화 된 언어!
(4)메모리 사용량이 적고, 다양한 가전제품에 적용
• 내장형 시스템(Embedded System) 요구 충족
• 가전제품: 작은 양의 메모리를 가지는 제어장치
자바언어의 특징
자바의 플랫폼 독립성
(1) WORA (Write Once, Run Anywhere)
한 번 작성된 코드가
모든 플랫폼에서바로 실행 가능하다
• 기존 언어(C/C++)의 플랫폼 종속성 문제를 극복
• OS(운영체제), H/W(하드웨어)에 상관없이 동일한 실행 환경 제공
• 네트워크에 연결된 어느 클라이언트에서나 실행: 웹 브라우저, 분산 환경 지원
(2) WORA를 가능하게 하는 자바의 특징
[ 바이트코드 (Bytecode) ]
• 자바 소스를 컴파일하여 생성된 목적 코드
• 특정 CPU에 종속되지 않은 중립적인 코드
• JVM(Java Virtual Machine)에 의해 해석되고 실행가능한 이진(binary) 코드
[ 자바 가상 머신 (JVM - Java Virtual Machine) ]
• 바이트코드를 실행하는 가상 기계(소프트웨어)
• 운영체제(OS)와 독립적으로 동작
• 각 플랫폼(OS)별로 JVM만 설치하면 자바 프로그램 실행 가능
(3) 객체지향 언어
자바 배포판
오라클은 개발 환경에 따라 다양한 자바 베포판 제공
[ Java SE ]
• 자바 표준 베포판(Standard Edition)
• 데스크탑과 서버 응용 개발 플랫폼
[ Java ME ]
• 자바 마이크로 베포판 (Micro Edition)
• 휴대전화나 PDA, 셋톱박스 등 성능/자원이 제한적인 하드웨어 응용 개발을 위한 플랫폼
• 가장작은메모리필요
• JavaSE의 일부 + 임베디드 시스템 및 가전제품을 위한 API 정의
[ Java EE ]
• 자바 기업용 베포판 (Enterprise Edition)
• 자바를 이용한 다중 사용자, 기업용 응용 개발을 위한 플랫폼
• JavaSE + 인터넷 기반의 서버 사이드 컴퓨팅관련 API 추가
자바 개발도구
JVM < JRE < JDK의 포함관계를 가진다
[ JVM (Java Virtual Machine) - 자바 가상 머신 ]
• 자바 바이트코드를 실행하는 소프트웨어
• 모든 (HW)플랫 폼에 설치: 플랫폼마다 다른 JVM이 존재하지만, 동일한 실행 환경 제공
• JVM 자체는 플랫폼에 종속적, 다양한 회사에서 공급
• JVM은 바이트코드를 해석하여 CPU가 실행할 수 있는 기계어로 변환
| 단계 | 역할 |
|---|---|
| 클래스 로딩 | .class 파일을 JVM에 로드 |
| 바이트코드 검증 | 코드의 안정성 검사 |
| 실행 (인터프리터 & JIT) | 바이트코드를 CPU가 이해하는 기계어로 변환 |
| 가비지 컬렉션(GC) | 더 이상 사용되지 않는 객체 제거 |
바이트코드(Bytecode)란?
• 자바 소스를 컴파일한 결과물(완전한 기계어가 아닌 중간단계의 코드)
• 특정 CPU에 종속되지 않는 중립적인 코드
• JVM에 의해 해석되고 실행되며,.class파일에 저장됨
• 모든 운영체제에서 동일한 실행 환경 제공
• 자바 가상 기계가 해석하는(인터프리터) 방식으로 바이트 코드 실행
• 자바 가상 기계가 작동준인 플랫폼에서 실행
[ JRE (Java Runtime Environment) - 자바 실행 환경 ]
• 자바 프로그램을 실행하기 위한 환경
• JVM과 자바 API(라이브러리)들이 들어있는 모듈파일
• 개발자가 아닌 일반 사용자는 JRE만 설치하면 자바 프로그램 실행 가능
[ JDK (Java Development Kit) - 자바 개발 키트 ]
• 자바 애플리케이션을 개발하고 실행할 수 있는 도구 모음
• JDK는 JRE와 추가적인 개발 도구(컴파일러, 디버거 등)를 포함
• 자바 코드를 작성하고 실행하려면 반드시 JDK가 필요
• 표준판(SE), 기업판(EE)
• JDK의 bin/파일함(directory, folder)에 포함된 주요 개발 도구
| 개발 도구 | 역할 |
|---|---|
| javac | 자바소스를 바이트코드로 변환하는 컴파일러 |
| java | 자바 응용프로그램 실행기, 자바 가상 기계를 작동시켜 자바프로그램을 실행 |
| javadoc | 자바 소스로부터 HTML 형식의 API 문서(document) 작성 |
| jar | 자바 클래스들(패키지포함)을 압축한 자바 아카이브 파일(.jar) 작성 관리 |
| jmod | 자바의 모듈 파일(.jmod)을 만들거나 모듈 파일의 내용 출력 |
| jlink | 응용프로그램에 맞춘 맞춤형(custom) JRE 제공 |
| jdb | 자바 응용프로그램의 실행 중 오류를 찾는 데 사용하는 디버거 |
| javap | 클래스 파일의 바이트 코드를 소스와 함께 보여주는 디어셈블러 |
자바 실행과정
자바 실행환경
[실행 환경]
자바가상기계 + 자바 플랫폼의 클래스 라이브러리(자바 API)
[응용프로그램 실행]
• main() 함수(method)를 가진 class의 main()에서 시작
• JVM이 필요할 때 클래스 파일을 탑재함: 적은 메모리로 실행가능
자바와 C/C++의 실행방식 차이
| 비교 | Java | C/C++ |
|---|---|---|
| 자바원시파일(-.java) 컴파일러 바이트코드(-.class) 하드웨어 - 운영체제 - JVM - 자바프로그램 |
C 원시파일(-.cpp) 컴파일러/링커 바이너리 실행 파일(-.exe) 하드웨어 - 운영체제 - C/C++ 프로그램 |
자바 실행과정
(1) 소스 코드 작성
개발자가
.java파일을 작성한다
public class Hello {
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
(2) 컴파일 (javac)
작성된 소스 코드는
javac(Java Compiler)에 의해 바이트코드로 변환된다
• 컴파일 후Hello.class파일이 생성
• 이 파일은 CPU가 직접 실행할 수 없는 바이트코드로 이루어져 있음
javac Hello.java
(3) 클래스 로딩 (JVM이 .class 파일 로드)
• JVM의 Class Loader가 .class 파일을 메모리에 적재
• 필요한 클래스들을 동적으로 로딩하여 실행
(4) 실행 (JVM이 바이트코드 해석)
• 인터프리터(Interpreter) 방식으로 바이트코드를 한 줄씩 해석하며 실행
• 또는 JIT(Just-In-Time) 컴파일러를 통해 기계어로 변환하여 성능 최적화
• 최종적으로 CPU가 실행
java Hello
출력:
Hello, Java!
(6) 프로그램 종료
프로그램 종료 시, JVM이 사용한 메모리를 해제하고 실행을 종료
자바 실행 과정의 핵심 흐름
.java (소스 코드)
↓ [javac 컴파일]
.class (바이트코드)
↓ [JVM 실행]
CPU에서 실행 (Machine Code)
자바의 프로그램 구조
자바 프로그램은 클래스(Class) → 메서드(Method) → 문장(Statement) 으로 구성된다
[ A.java ]
// 1. 패키지 선언 (필수는 아님)
package mypackage;
// 2. 클래스 선언
public class A {
// 3. main 메서드 (프로그램의 시작점)
public static void main(String[] args) {
// 4. 변수 선언 및 초기화
int number = 10;
// 5. 메서드 호출
printMessage(number);
}
// 6. 사용자 정의 메서드 (기능 정의)
public static void printMessage(int num) {
System.out.println("입력된 숫자: " + num);
}
}
JDK와 메모리 영역
JVM(Java Virtual Machine)은 자바 프로그램을 실행하기 위해 여러 개의 메모리 영역(5개)을 관리한다
• 메서드(Method) 영역 (또는 클래스 영역)
• 힙(Heap) 영역
• 스택(Stack) 영역
• PC 레지스터(Program Counter Register)
• 네이티브 메서드 스택(Native Method Stack)
JVM 메모리 영역의 종류
메서드 영역 (Method Area)
클래스 메타데이터를 저장하는 공간
• JVM이 로드한 클래스 정보, 정적(static) 변수, 상수, 메서드 코드, 인터페이스 정보 등이 저장됨
• 모든 스레드(Thread)가 공유하는 영역
• 런타임 상수 풀(Runtime Constant Pool) 포함 → 상수(리터럴, 상수 문자열) 저장
class Example {
static int staticVar = 10; // 메서드 영역에 저장
}
[ 힙 영역 (Heap Area) ]
객체(인스턴스)와 배열이 저장되는 공간
• new 키워드를 사용해 생성한 객체가 저장됨
• 가비지 컬렉션(GC, Garbage Collection)에 의해 관리됨
• 모든 스레드가 공유하는 영역
class Example {
int instanceVar = 20; // 힙 영역에 저장
}
public class Main {
public static void main(String[] args) {
Example obj = new Example(); // obj는 힙 영역에 저장
}
}
[ 스택(Stack) 영역 ]
각 메서드 호출 시 생성되는 메모리 영역
• 메서드 실행에 필요한 지역 변수, 매개변수, 연산 중간값, 리턴 값 등이 저장됨
• 메서드 호출 시 새로운 스택 프레임(Stack Frame)이 생성되고, 메서드가 종료되면 제거됨
• 스레드별로 개별적으로 존재 (스레드마다 하나의 스택을 가짐)
public class Main {
public static void main(String[] args) {
int num = 10; // 스택 영역에 저장
add(num); // add 메서드 호출 -> 새로운 스택 프레임 생성
}
public static void add(int x) {
int result = x + 5; // 스택 영역에 저장
}
}
[ PC 레지스터 (Program Counter Register) ]
JVM이 실행 중인 명령어 주소(현재 실행 중인 바이트코드 위치)를 저장하는 공간
• 스레드마다 하나씩 존재 → 각 스레드가 실행할 명령어의 위치를 추적
• 자바 바이트코드 명령어를 순차적으로 실행할 때 사용됨
[ 네이티브 메서드 스택 (Native Method Stack) ]
C, C++과 같은 네이티브 코드(C언어 기반 라이브러리)를 실행할 때 사용되는 스택
• JNI(Java Native Interface)를 통해 실행되는 네이티브 메서드 호출 시 사용됨
• 예를 들어, JNI를 사용하여 C++ 메서드를 호출할 때 사용됨
public class Example {
public native void nativeMethod(); // 네이티브 메서드 선언
}
JVM 메모리 구조 요약
| 메모리 영역 | 역할 | 특징 |
|---|---|---|
| 메서드 영역 (Method Area) | 클래스 정보, static 변수, 메서드 코드 저장 |
모든 스레드가 공유 |
| 힙 영역 (Heap Area) | new로 생성한 객체 저장 |
모든 스레드가 공유, GC 관리 |
| 스택 영역 (Stack Area) | 지역 변수, 메서드 호출 정보 저장 | 스레드별 개별 생성 |
| PC 레지스터 (PC Register) | 현재 실행 중인 명령어 주소 저장 | 스레드별 개별 존재 |
| 네이티브 메서드 스택 (Native Stack) | 네이티브 코드(C, C++) 실행 | JNI 호출 시 사용 |
JVM 메모리 관리 - 가비지 컬렉션(GC)
• JVM은 힙 영역의 불필요한 객체를 자동으로 제거(Garbage Collection)
• GC는 더 이상 참조되지 않는 객체를 탐색하여 메모리를 해제
• System.gc();를 호출하여 GC 실행 요청 가능하지만, 보장되지 않음
Example obj1 = new Example();
Example obj2 = new Example();
obj1 = null; // obj1이 참조하는 객체는 GC 대상