Java의 특징
- "Programmers Write Once, Run Anywhere(WORA)" 이는, JVM이라는 Java 가상머신 위에서 동작하기 때문에 가능하다. 가상머신이란 프로그램의 실행하기 위해 물리적 머신과 유사한 머신을 소프트웨어로 구현한 것임.
- JVM의 역할은 자바 애플리케이션을 클래스 로더를 통해 읽어 들여 자바 API와 함께 실행하는 것.
- JVM은 JAVA와 OS사이에서 중개자 역할을 수행. JAVA가 OS에 구애받지 않고 재사용을 가능하도록 함. 메모리관리, Garbage collection을 수행함.
Java의 장점
- 간결한 객체지향 언어
- Garbage Collection을 통한 메모리 관리
- 플랫폼에 종속적이지 않고, 한번 컴파일 된 프로그램은 어느 운영체제나 환경에서 동일하게 실행을 보장
- 많은 오픈소스 프레임워크를 통해 생산성증가
Java의 단점
- 처리속도가 중요한 프로그램에는 맞지 않음
- 최근 나오는 프로그래밍언어에 비해 간결하지 못함
- 하드웨어를 직접 컨트롤할 수 없음
- GUI가 많은 프로그램에는 적합하지 않음
Java의 생태계

자바 표준 스펙 : 자바는 이렇게 만들어야 한다는 설계도이며, 문서이다. 이 표준 스펙을 기반으로 여러 회사에서 실제 작동하는 자바를 만든다. 자바 표준 스펙은 자바 커뮤니티 프로세스(JCP)를 통해 관리된다.
자바 구현 : 여러 회사에서 자바 표준 스펙에 맞추어 실제 작동하는 자바 프로그램을 개발한다. 각각 장단점이 있다. 예를 들어 Amazon Corretto는 AWS에 최적화 되어 있다.
자바소스코드 실행순서

- 소스 코드 작성: 자바 소스 코드로 이루어진 .java 파일을 개발자가 생성합니다.
- .java 파일: 소스 코드 파일로, 작성한 코드가 저장
- 컴파일: JDK에 포함되어있는 자바 컴파일러(javac)가 소스 코드를 바이트코드로 컴파일해서 .class 파일로 저장합니다. 이때, 자바가상머신JVM에서 더 빠르게 실행될 수 있게 최적화하고 문법 오류도 검출한다.
- .class 파일: 컴파일 후에 생성되는 실행 파일
- JVM: 바이트코드로 작성된 자바 클래스 파일을 실행할 수 있는 가상 머신

3. 메모리에 로딩: 프로그램이 실행되면 클래스 로더가 컴파일된 .class 파일을 찾아서 JVM이 사용하는 메모리 공간에 올립니다.
- 클래스 로더: 계층형 구조로 설계, 클래스의 중복 로드를 방지함.
- Bootstrap class Loader가 가장 기본적인 Java class 파일을 올리고,
- 그다음 extensionclassloader가 확장 java class 파일
- 그다음 application class loader가 개발자가 개발한 java class와 라이브러리 파일을 메모리에 올린다. 올린다.

4. JVM이 프로그램 실행: JVM에 할당된 런타임 데이터 영역에 로드된 바이트코드를 실행 엔진이 (1) 인터프리터로 해석하거나 (2) JIT 컴파일러를 통해 기계어(바이너리코드)로 변환하여 실행합니다.
a. 바이트코드
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello, World!
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
b. 기계어

- 런타임 데이터 영역: 메서드, 힙, 스택, PC 레지스터, 네이티브 메서드 영역으로 나누어 관리
- 실행 엔진이 메서드 영역에 로드된 바이트 코드를 실행
- JIT 컴파일러가 자주 호출되는 메서드의 바이트 코드를 기계어로 변환

5. About JVM
(1) Class Loader
JVM 내로 클래스 파일을 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈입니다. 런타임 시에 동적으로 클래스를 로드합니다.
(2) Execution Engine
클래스 로더를 통해 JVM 내의 Runtime Data Area에 배치된 바이트 코드들을 명렁어 단위로 읽어서 실행합니다. 최초 JVM이 나왔을 당시에는 인터프리터 방식이었기때문에 속도가 느리다는 단점이 있었지만 JIT 컴파일러 방식을 통해 이 점을 보완하였습니다. JIT는 바이트 코드를 어셈블러 같은 네이티브 코드로 바꿈으로써 실행이 빠르지만 역시 변환하는데 비용이 발생하였습니다. 이 같은 이유로 JVM은 모든 코드를 JIT 컴파일러 방식으로 실행하지 않고, 인터프리터 방식을 사용하다가 일정한 기준이 넘어가면 JIT 컴파일러 방식으로 실행합니다.
(3) Garbage Collector
Garbage Collector(GC)는 힙 메모리 영역에 생성된 객체들 중에서 참조되지 않은 객체들을 탐색 후 제거하는 역할을 합니다. 메모리 할당 후 해체가 안되면 메모리 누수가 발생함. 이를 방지하기 위해서 Java에서는 가비지 컬렉터를 도입하여 동적으로 할당된 메모리 영역 중 더이상 참조되지 않는 영역을 제거를 진행함. 이때, GC가 역할을 하는 시간은 언제인지 정확히 알 수 없습니다. 그러나, 가비지 컬렉션이 실행될 때 'Stop the world'가 발생하여 Garbage Collection의 빈번한 발생은 어플리케이션 성능에 좋지 않음.
(4) Runtime Data Area
JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역입니다. 이 영역은 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack로 나눌 수 있습니다.
인텔리제이 역할 : 인텔리제이는 자바 코드를 실행 할 때 이 과정을 자동으로 처리해준다. 인텔리제이에서 자바 코드를 실행하면 컴파일과 실행을 모두 한번에 모든 클래스를 대상으로 한꺼번에 처리한다. (단, 인텔리제에서 class 파일을 접속해보이면 소스코드처럼 보이나 실은 바이트코드가 decompile된 코드로 주석이 사라져있음)
(5) JVM 프로퍼티
JVM 프로퍼티는 JVM(Java Virtual Machine)의 실행 환경을 제어하는 설정값으로, 주로 애플리케이션 동작, 메모리 관리, 디버깅, 클래스 로딩 등을 제어하는 데 사용됩니다.
자바와 운영체제 독립성
일반적으로 프로그램(윈도우프로그램.exe)은 다른운영체제에서 실행할 수 없다. 자바는 자바가 설치된 모든 OS에서 실행할 수 있다. 그 이유는 컴파일된 바이너리파일은 JVM이라는 가상환경에서 운영되어, JVM은 각 운영체제에 맞는 코드로 변환시켜주는 역할을 한다. 그러므로 개발자는 개발환경과 운영환경의 차이를 고려할 필요없이 개발을 진행하면 된다.
그렇다면, 운영체제 종속적인 프로그램을 쓰는 사람들은 왜?
1. Native Performance and Optimization
- Platform-independent languages, like Java, may not achieve the same level of performance as native languages (like C or Swift) optimized specifically for a particular OS.
2. Access to OS-Specific Features
- Many applications, especially those that interact closely with the operating system (e.g., system utilities, hardware drivers, or graphics-intensive applications), rely on OS-specific features.
Java의 동작원리
작성된 Java소스코드는 JDK에 포함되어있는 컴파일러를 통해서 클래스파일(바이너리파일)로 변환됨. 변환된 파일은 JVM의 Class Loader에 의해 JVM에서 불러와지게 되며 실행되게되며

JDK와 JRE
- JDK(Java Development Kit)
Java를 개발함에 있어 필요한 모든 집합체. JRE를 포함하고 있으며, 그 외에 javadoc, 컴파일러를 포함(javac)
- JRE(Java Runtime Environment)
Java를 실행함에 있어 필요한 환경을 포함. JVM을 포함하고 있으며, 그 외에 java class library, java 명령어들을 포함
The JDK : The JDK is a software development kit required to develop Java applications and applets by Oracle Corporation. It includes the Java Runtime Environment (JRE), an interpreter/loader (Java), a compiler (javac), an archiver (jar), a documentation generator (javadoc), and other tools needed to develop Java applications.
- An applet : a type of Java program designed to be embedded and executed within a web browser or applet viewer environment, providing interactive features to web pages.`
- Java Runtime Environment (JRE): This provides the libraries, the Java Virtual Machine (JVM), and other components to run Java applications and applets. Essentially, it's the environment in which Java programs run.
- runtime : In the context of Java, "runtime" refers to the period during which a Java program is executing. The term can also refer to the software components necessary for running Java applications, most notably the Java Runtime Environment (JRE).
- Java Compiler (javac): Converts your Java code into bytecode.
- Java Virtual Machine (JVM): A part of JRE that runs the bytecod
자바의 메모리구조
- 메서드 영역(Method Area): 메서드 영역은 프로그램을 실행하는데 필요한 공통 데이터를 관리한다. 이 영역은 프로그램의 모든 영역에서 공유한다.
- 1. 클래스 정보: 클래스의 실행 코드(바이트 코드), 필드 생성코드, 메서드 코드와 인스턴스 생성자 코드 등 모든 실행 코드가 존재한다. 붕어빵의 틀을 보관한다.
- 2. static 영역: `static` 변수들을 보관한다.
- 3. 런타임 상수 풀: 프로그램을 실행하는데 필요한 공통 리터럴 상수를 보관한다. 프로그램을 효율 적으로 관리하기 위한 상수들을 관리한다.
- 스택 영역(Stack Area): 실제 프로그램이 실행되는 영역. 메소드 실행할때마다, 하나의 실행 스택이 생성된다. 각 스택 프레임은 지역 변수, 중간 연산 결과, 메서드 호출 및 회귀정보 등을 포함한다.
- 스택 프레임: 스택 영역에 쌓이는 메모리 공간이 하나의 스택 프레임이다. 메서드를 호출할 때 쌓이고, 종료되면 제거된다.
스택 영역은 각 쓰레드별로 하나의 실행 스택이 생성된다. 따라서 쓰레드 수 만큼 스택 영역이 생성된다.
- 스택 프레임: 스택 영역에 쌓이는 메모리 공간이 하나의 스택 프레임이다. 메서드를 호출할 때 쌓이고, 종료되면 제거된다.
- 힙 영역(Heap Area)**: 동적으로 배치되는 데이터가 쌓이는 곳이다. 객체(인스턴스)와 배열이 생성되는 영역이다. 가비지 컬렉션(GC)이 이루어지는 주요 영 역이며, 더 이상 참조되지 않는 객체는 GC에 의해 제거된다.
- 클래스 정보를 활용하여 생성된 인스턴스가 존재함. 붕어빵틀(메소드영역, 클래스)로부터 생성된 붕어빵이 존재함.
- 인스턴스 내부의 변수 값은 서로 다를 수 있지만, 메서드는 공통된 코드를 공유한다. 따라서 객체가 생성될 때, 인스턴스 변수에 는 메모리가 할당되지만, 메서드에 대한 새로운 메모리 할당은 없다. 메서드는 메서드 영역에서 공통으로 관리되고 실행된다.
- 자식이 생성될때, 부모의 생성자가 먼저 작동되어 부모가 먼저 생성되고 그 이후에 자식이 생성됨.
- 개발상황에서 응용 : 특정 변수에 String을 저장해야할 때, 여러 객체에서 자주 사용한다면 static field으로 설정하는 것이 메모리 관리상 유리하다. method 내에서 저장되는 것은 stack 영역에 method가 실행될 때 마다 새로 쓰이고 지워지고를 반복하며, instance field에 저장되는 것은 동일한 객체 내에서는 공유가 가능하나 객체 간에서는 공유가 불가능하며 heap영역이 과도하면 Garbage Collection이 자주 발생함. 그러므로 모든 객체에서 공유가능한 static field에 저장하는 것이 유리함.
클래스와 메모리구조
- 인스턴스 생성시에 인스턴스 변수가 생기며 이를 Heap 영역에 보관된다. 인스턴스는 클래스의 메타데이터를 pointer로 가리킨다.
- 클래스의 메타데이터는 메소드의 코드위치를 저장하고 있다. 메소드는 클래스 정보 생성과 함께 메소드영역에 보관된다.
JVM 프로퍼티
- 사용자 정의 프로퍼티 : 사용자 정의 프로퍼티를 애플리케이션에서 전달하고 사용할 수 있습니다.
- Spring Boot 관련 : JVM이 Profile 값을 SpringBoot에 전달하는 관문 역할을 수행
- Profile 활성화 : java -Dspring.profiles.active=dev -jar myapp.jar
- 외부 설정 파일 경로 지정: java -Dspring.config.location=/path/to/application.yml -jar myapp.jar
- 메모리 관리 : 힙 메모리 크기 조정: java -Xms512m -Xmx1g -jar myapp.jar
- 가비지 컬렉션(Garbage Collection) : GC 알고리즘 설정, GC 로그 출력
- 디버깅 및 모니터링
- 클래스 로딩
- JIT 컴파일러 관련
Profile 설정 | -Dspring.profiles.active=dev |
메모리 관리 | -Xms512m -Xmx1g, -XX:MetaspaceSize=128m |
GC 설정 | -XX:+UseG1GC, -Xlog:gc*:file=gc.log:time,uptime,level,tags |
디버깅 | -agentlib:jdwp=transport=dt_socket,server=y,address=*:5005 |
클래스 로딩 | -verbose:class, -cp /path/to/classes |
JIT 컴파일러 | -XX:+PrintCompilation, -Djava.compiler=NONE |
로케일/인코딩 | -Duser.language=en, -Dfile.encoding=UTF-8 |
네트워크 | -Dhttp.proxyHost=proxy.example.com, -Dnetworkaddress.cache.ttl=0 |
자바 명령어
- java -jar myapp.jar : JAR 파일 실행
- java -classpath : 자바 애플리케이션을 실행할 때, 클래스(.class), 라이브러리(JAR) 파일 등을 어디서 로드할지 지정하는 경로예요.
- When you use -jar, Java uses the classpath defined inside the JAR’s manifest file (MANIFEST.MF), specifically:
명령어 | 설명 |
java -version | Java 런타임 버전 확인 |
javac FileName.java | Java 파일 컴파일 |
java FileName | Java 애플리케이션 실행 |
jar cf myapp.jar *.class | JAR 파일 생성 |
javadoc -d docs | Java 도큐먼트 생성 |
javap -c ClassName | 클래스 디컴파일(바이트코드 보기) |
java -Xms512m -Xmx1024m | 메모리 크기 설정 |
'개발기술 > Java' 카테고리의 다른 글
웹 스크래핑 Jsoup (0) | 2024.08.06 |
---|---|
Java Dependency - Marven, Gradle, exteral libraries(Lombok etc) (0) | 2024.07.05 |
Java 코딩구현 - Java I/O (1) | 2024.06.14 |
Java 구현 - 변수, 데이터타입, 컬렉션 (0) | 2024.05.22 |
Java : 범용 library 및 Annotation (0) | 2024.05.05 |