티스토리 뷰
첫번째 미션이다.
초급
1. JVM(Java Virtual Machine)이 자바 프로그램을 실행할 때 하는 주요 역할을 설명하세요. JVM이 자바 프로그램을 운영체제와 독립적으로 실행할 수 있게 해주는 이유는 무엇인가요?
사실 자바프로그램을 실행하기 위해서 JVM이 필요하다는 것을 알고 난 후 왜 굳이 가상머신이 필요할지 궁금했다. 이유는 4가지 정도로 볼 수 있다.
첫번째는 강의를 들으면서 더욱 잘 알게된 사실이지만 플랫폼 독립성 때문이다.
C와 C++의 경우 OS마다 다른 실행 파일 형식이 필요하다. .exe, ELF 등
하지만 자바의 경우 하나의 바이트코드로 모든 OS에서 실행 가능하다. JVM이 각 OS에 맞게 해석해서 실행한다.
두번째는 편하다는 것이다.
한번의 작성으로 모든 플랫폼을 지원하기 때문에 코드의 재사용성이 증가한다. 다수의 OS를 사용해야 한다고 했을 때 유지보수가 편리할 것이다.
세번째는 보안적인 측면 때문이다.
JVM은 중간에서 코드 검증을 한번 해준다. 작성된 코드가 시스템에 직접적으로 접근하는 것을 제한해서 위험을 예방한다. 그리고 메모리 관리를 자동으로 해준다.
마지막은 성능 최적화에 좋기 때문이다.
JVM도 일종의 캐싱을 수행해서 성능을 최적화하는데 예로 JIT(Just In Time)가 있다. 프로그램 실행 중 실시간으로 코드를 컴파일하는 방식이다. JIT은 초기에는 인터프리터로 바이트코드를 실행한 뒤 자주 실행되는 코드에 대해서 네이티브 코드(기계어)로 컴파일 해놓고 사용하는 방식으로 최적화를 제공한다. 다른 최적화 기능도 한다.
JVM의 주요기능은 다음과 같다.
- 바이트코드 실행
- .class 파일(바이트코드) 읽기
- 바이트코드 검증
- 실행 (인터프리터 + JIT 컴파일)
- 메모리 관리
- 객체 생성/제거
- 가비지 컬렉션
- 메모리 영역 관리 (힙, 스택 등)
- 보안
- 코드 검증
- 접근 권한 확인
- 시스템 리소스 보호
- 멀티스레딩
- 스레드 생성/관리
- 스레드 동기화 지원
JVM이 자바프로그램을 OS와 독립적으로 실행할 수 있는 이유
당연히 OS위에서 바로 프로그램을 실행하려면 해당 환경에 종속적일 수 밖에 없다. 이것을 JVM이라는 가상 머신은 중간 계층의 역할을 해줌으로써 독립적으로 실행할 수 있게 해준다.
- 자바 프로그램 → JVM
- 자바 코드를 작성한다.
- JVM → OS
- Windows : Windows API 호출
- Linux : Linux 시스템 콜 호출
- Mac : Mac OS 시스템 콜 호출
이런 식으로 자바 프로그램을 작성할 때 모두 동일한 인터페이스를 제공하고 OS에 각 환경에 맞는 방식으로 변환해준다.
2. 자바 주석을 사용하는 기본적인 이유를 설명하고, 주석을 작성하는 두 가지 방법을 각각 예시와 함께 설명하세요.
주석은 작성한 코드의 이해를 높이기 위해 사용된다. 수작업으로 코드 하나하나에 적어줄 수도 있고 API 문서를 특정 형식으로 자동 생성해주는데 쓰이기도 한다.
코드 작성에 대한 강의를 들으면서 배운 것이 만약 리팩토링이 필요한 코드인데 현재 하기에는 시간과 비용이 필요이상으로 드는 경우 나중에 할일로 TODO처리를 해놓은 역할도 하는 것을 알았다.
실제 출력값을 보기 위해 프린트문을 썼던 것도 주석으로 남겨두는 경우도 있다고 한다.
주석 작성 방법 2가지
// 1. 한 줄 주석
/*
2. 여러 줄 주석
2. 여러 줄 주석
2. 여러 줄 주석
*/
3. System.out.println()을 사용하여 자기소개를 콘솔에 출력하는 프로그램을 작성하세요.
System.out.println("안녕하세요!");
System.out.println("저는 이세은입니다.");
System.out.println("스터디 완주까지 다들 화이팅!!");
https://github.com/tdronnie/java-study/blob/main/src/mission/mission1.java
중급
1. JVM의 내부 구조 중 클래스 로더, 실행 엔진, 메모리 관리 역할에 대해 간단히 기술하세요.
JVM의 내부 구조는 class Loader, Runtime Data Area, Execution Engine으로 구성된다.
class Loader → Runtime Data Area → Execution Engine
바이트코드로 변환된 클래스파일을 JVM이 넘겨받게 되면 클래스 로더에게 가게 된다. 클래스 로더는 런타임 데이터 영역으로 바이트코드를 로드한다. 그리고 실행 엔진으로 코드가 보내져서 해석된다.
각 부분이 하는 일을 구체적으로 적자면
클래스 로더는 한 번에 JVM에 모든 클래스파일을 읽어오는 것이 아닌 애플리케이션에서 필요한 부분을 동적으로 로드한다. 런타임 데이터 영역에 링크를 이용해 코드를 배치한다.
런타임 데이터 영역은 실질적인 메모리를 할당받아 관리되는 영역이다. 메서드, 힙, 스택, PC Register, 네이티브 메서드 스택을 가지며 자바 애플리케이션을 실행할 때 사용되는 데이터가 적재된다.
실행 엔진은 런타임 데이터 영역에 배치된 바이트 코드를 명령어 단위로 읽어서 실행한다. 바이트코드를 네이티브코드로 바꾸어준다. 이 때 인터프리터와 JIT이 사용된다. garbage collector가 있어서 힙에서 더이상 사용하지 않는 메모리를 자동회수한다.
2. System.out.println()의 내부 동작 과정에서 PrintStream 클래스가 어떻게 작동하는지 설명하세요. 또한 println() 메서드가 어떤 방식으로 콘솔에 출력을 전달하는지 기술하세요.
System 클래스에는 PrintStream 타입의 out이라는 정적 필드가 있다.
System.out으로 정적 필드인 PrintStream 객체를 참조하고 println() 메서드를 호출하는 것이다.
입력을 읽거나 쓸 때 사용하는
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BuffereWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
과 비슷하게 PrintStream는 BufferedWriter → OutputStreamWriter → FileOutputStream 순서로 데이터가 전달된다.
구체적인 적자면 다음 순서로 진행된다.
- PrintStream 객체인 System.out의 println() 메서드를 호출
- 버퍼링
- BufferedWriter는 성능을 위해 바로 출력하지 않고 내용을 버퍼에 저장한다.
- 바이트로 변환각 OS의 문자 인코딩 방식을 사용한다.
- OutPutStreamWriter는 문자를 바이트로 변환해준다.
- OS로 전달
- FileOutPutStream이 변환된 바이트를 OS에 전달한다.
- OS가 콘솔에 최종 출력한다.
네이틔브 메서드를 통해서 시스템 콜을 부르고 I/O를 볼 수 있는 디바이스에 전달된다.
고급
1. JVM(Java Virtual Machine)의 구조와 역할을 상세히 설명하세요. JVM이 자바 프로그램을 실행하는 과정에서 클래스 로딩, 바이트코드 검증, JIT 컴파일 등이 수행되는 각 단계와 그 역할을 단계별로 서술하세요.
전반적인 흐름은 초중급에서 설명한 것 같으니 고급에서는 중요한 실행 단계에서의 구체적인 동작에 집중해보자!
먼저 JVM 내부로 클래스 파일을 로드하는 부분을 보자.
- loading
- 애플리케이션에서 필요한 경우 동적으로 로드한다. 로드되는 것들은 코어 Java API클래스들, 확장 클래스들, 사용자 정의 클래스들이 있다. 각 클래스들은 ClassLoader 클래스를 활용해 진행되지만 상속받아 커스텀할 수 있다.
- linking바이트코드를 검증하는데 포맷, 스택 오버플로우가 발생하는지, 타입이 잘 지켜졌는지 등 여러가지를 검사한다.해석 과정으로 자바 코드에서 상단에 위치하던 심볼릭 참조(java.lang.String 같은)을 실제 클래스 참조 형식으로 바꿔준다.
- 준비 과정으로 static 변수들에 대해 초기 메모리 할당을 한다.
- 그 다음 링킹을 하는데 일종의 검증과 준비, 해석단계를 거쳐서 클래스들을 준비한다.
- initialization
- 마지막으로 클래스 변수들을 초기화한다.
클래스 파일이 로드된 후 실행되어야 사용자가 작성 자바파일이 동작된다.
실행 엔진에서는 런타임 데이터 영역에 로드된 바이트 코드를 읽어 실행하는데 명령어 단위로 읽어서 실행한다. 클래스파일의 바이트코드를 네이티브 코드로 변경해주어야 한다. 이 때 사용되는 것이 인터프리터와 JIT이다.
인터프리터는 속도는 느리다. 단순 있는 명령어를 읽어서 해석하고 실행하는 역할을 한다.
JIT은 먼저 전체 컴파일을 진행한 뒤 캐싱을 한다. 이후에는 해당 기계코드를 활용하는 방식이다.
사실 JVM 내부는 클래스 로더, 런타임 데이터 영역, 실행 엔진 말고 네이티브 메서드를 처리하는 부분도 있다.
자바 네이티브 메서드 인터페이스라 하고 JNI라고도 한다. 전에 스프링에서 외부에서 작성된 라이브러리를 사용하기 위해서 사용해본적이 있다. JNI는 JVM위에서 실행되는 자바 코드가 네이티브 응용프로그램이나 외의 언어로 작성된 라이브러리를 호출할 때 사용하는 프레임워크다.
2. 자바의 System 클래스는 상속하거나 인스턴스화할 수 없도록 설계되어 있습니다. 이 설계가 자바의 객체지향 원칙에 어떻게 부합하는지 설명하고, 이로 인해 얻을 수 있는 장점에 대해 서술하세요. (힌트: 싱글톤 패턴과 캡슐화 관점에서 설명해 보세요.)
System 클래스는 시스템의 핵심 기능을 담당하는 클래스이다.
입출력 등의 딱 시스템 수준의 작업만을 처리한다. 단일책임의 원칙을 지키고 있다고 볼 수 있다.
기능들은 개방되어 있어서 사용할 수 있지만 생성자도 private 처리되어있고 내부 동작도 네이티브 메서드로 밖에서 볼 수 없다. 이처럼 구체적인 구현은 final을 사용해 확장 불가능하므로 개방 폐쇄 원칙을 지키고 있다고 볼 수 있다.
이 때문에 자원 접근에 제한을 걸어 데이터를 보호한다. 상태 관리가 용이해진다. 또 시스템의 접근을 블랙박스 처리하므로 JVM처럼 플랫폼 독립성도 확보할 수 있을 것이다.
사용자에 입장에서는 인스턴스 생성을 하지 않아도 되고 어느 프로그램에서나 동일한 방식으로 기능을 사용할 수 있어 일관성을 가진다.
'Java' 카테고리의 다른 글
성빈클럽mission3 - 연산자, 회로 단락 평가 (3) | 2024.10.31 |
---|---|
성빈클럽mission2 - 변수와 JVM에서의 관리 (2) | 2024.10.31 |
[Eclipse]pom.xml xml태그 적용에러/Failed to create the part's controls 에러/이클립스 uninstall (0) | 2022.05.15 |
[Eclipse]프로젝트 import시 빨간색x박스에러+java.lang.UnsupportedClassVersionError (0) | 2022.03.03 |
[Eclipse]jvm is not suitable for this product (0) | 2022.03.03 |
- Total
- Today
- Yesterday
- jvm
- 파이썬
- 자바
- x박스에러
- gradlew권한에러
- 도커
- 스터디
- 성빈클럽
- An error has occured
- docker-compose
- vscode
- 회로 단락 평가
- eclipse 삭제
- tuple
- 형변환
- xml태그적용 에러
- Java
- travis CI 에러
- 엘리스코딩
- UnsupportedClassVersionError
- 자바 입문
- 딥러닝
- .travis.yml 빌드에러
- docker
- 애자일로 가는 길
- 오늘부터 개발자
- WSL2
- 함께 자라기
- Eclipse
- jvm is not suitable for this product
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |