자바 스터디 1주차

기석·2022년 4월 26일
0
post-thumbnail

1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가. #1

목표

자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기.


학습할 것

JVM이란 무엇인가

학습 전

JVM은 Java Virtual Machine, 컴파일된 자바 바이트코드를 여러 운영체제 위에서 실행해주는 독립된 프로그램이다. JVM 덕분에 자바는 하나의 코드로 여러가지 운영체제 위에서 실행될 수 있다.

학습 후

JVM의 역할은 자바 애플리케이션을 클래스 로더를 통해 읽어들여 자바 API와 함께 실행하는 것이다. 그리고 JVM은 OS와 JAVA사이 중개자 역할을 수행하여 OS에 구애받지 않고 재사용할 수 있게 해준다. 그리고 자바의 중요한 부분인 메모리 관리도 수행하며 스택 기반으로 동작한다.

+클래스 로더, 자바 API, 메모리 관리(GC), 스택 기반

컴파일 하는 방법

학습 전

JDK를 설치하고 javac ~.java하면 컴파일된 파일이 나오고 java -jar ~.java하면 실행되었던 것 같은데, 사실 javac가 맞는지도 컴파일된 파일 확장명이 무엇인지도 잘 모르겠다.

학습 후

기본적인 방법은 javac ~.java 하는 것이 맞다. 다만 컴파일된 파일의 확장명은 class이다.
그리고 추가하자면 옵션을 통해 classpath 디렉터리, 인코딩, 소스패스, 빌드할 자바 버전, 부트스트랩, extdirs 디렉터리 등을 지정할 수 있고 디버깅, 경고, 출력을 켜거나 끌 수 있다.
자세한 설명과 더 많은 옵션은 공식문서에있다.
오 그리고 한 파일 안에 클래스 여러개가 있어도 클래스마다 파일이 생성된다.

+컴파일된 파일은 class, 다양한 컴파일 옵션

실행하는 방법

학습 전

위에서 써버렸는데 컴파일/빌드 후에 java -jar ~.java하면 실행된다. 이거는 사실 아까 스프링 공부하면서 알았다. 근데 자바에 빌드는 없었던가? 빌드는 안물어보는게 꺼림칙하다.

학습 후

스프링 공부하면서 썼던 것은 지금보니 .jar파일 실행하는 방법이었다.
java파일을 class파일로 컴파일 한 뒤, java [ClassName]으로 실행한다.
자바 실행도 컴파일과 마찬가지로 많은 옵션을 줄 수 있다.
-server, client 옵션: 초기구동, 큰 작업의 성능과 관련돼있다. 지금은 안쓴다고 한다.
java 옵션에 대한 공식 문서
-jar jar파일을 실행시킨다.
-classpath ".;lib"는 . , lib 순서로 탐색하며 필요한 class들을 찾는다는 뜻이다.
;는 경로 구분자.

class path 관련 생활코딩 영상
https://youtu.be/otnQaFoS8Oc

바이트코드란 무엇인가

학습 전

때려맞혀보자면 바이트코드는 기계어보단 high level일 것이고 그러면 뭐 JVM이 알아 들을 수 있는 코드 일테니 자바 클래스 파일을 컴파일 혹은 빌드하면 나올 것이다. 그리고 바이트니까 명령어들의 집합일 것이라는 느낌이있다. 아 근데 컴파일인지 빌드인지 둘 다 인지 모르겠다.

학습 후

자바 바이트코드는 자바 가상 머신이 이해할 수 있는 언어로 변환된 소스 코드를 의미한다.
자바 컴파일러에 의해 변횐되는 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불리고 있다. 이러한 자바 바이트 코드의 확장자는 .class이다.
자바 바이트 코드는 자바 가상 머신만 설치되어 있다면 어떤 운영체제라도 실행 될 수 있다.

+대충 때려맞춘 것이 어느정도 맞았다. 바이트 코드의 확장자는 .class라는 건 몰랐다. 빌드를 따로 안한다는 것도 알았다. 따지자면 JIT가 빌드랑 비슷하지 않을까

JIT 컴파일러란 무엇이며 어떻게 동작하는지

학습 전

JIT 컴파일러란, Just In Time을 말하는데, JVM이 런타임 환경에서 자주 사용되는 코드를 캐시에 저장해 속도를 최적화하는 기법이다.

학습 후

JIT 컴파일은 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일 기법이다. JIT 컴파일러는 전통적인 인터프리터와 컴파일 방식을 혼합한 방식으로 생각할 수 있다. 실행 시점에서 인터프리트 방식으로 기계어 코드를 생성하면서 캐싱하여 같은 함수가 여러 번 불릴 때 기계어 코드를 생성하는 것을 방지한다.

인터프리터보다 빠른 건 알겠고, 그냥 컴파일 하지 않고 이렇게 하는 이유도 궁금해졌는데,
실행 과정에서 컴파일을 할 수 있기 때문에 무조건 모두 컴파일하고 실행해야하는 컴파일 언어보다 빠른 응답속도를 가진다는 장점이 있었다. 그렇기 때문에 자바는 JIT 컴파일을 통해 인터프리터와 컴파일 언어의 장점을 모두 가지고 있다고 볼 수 있겠다.

+자주 사용되는 코드를 캐싱한다는 점만 알았는데, 바이트 코드를 실행 시점에 기계어로 바꾸는 것이 JIT임은 몰랐다. 필요한 부분은 JIT로 캐싱하고, 아닌 부분은 인터프리터로 실행한다고 한다. 조금 다른 이야기지만 JVM을 플랫폼 별로 개발하는 과정이 컴파일을 제작하는 과정보다 간단하다는 장점이 있다. 바이트코드에서 기계어 변환만 만들면되기 때문이다.

JVM 구성 요소

학습전

상상해보자면 바이트 코드를 해석할 인터프리터, 해석된 코드를 실행할 녀석, 가비지 컬렉터 이 외에 뭐가 더 필요한지 모르겠다.

JVM 구성요소
출처) https://asfirstalways.tistory.com/158

학습 후

클래스로더: JVM으로 클래스 파일을 로드시키는 역할. 모든 클래스 파일을 한 번에 올리는 게 아니라 필요할 때마다 동적으로 올려준다. 또 클래스 로더는 부트스트랩, 익스텐션, 시스템 클래스 로더로 나뉜다. 부트스트랩은 jdk내부클래스, 익스텐션은 자바 핵심 클래스, 시스템 클래스로더는 애플리케이션 레벨의 클래스들을 로드한다.

Execution Engine
클래스 로더가 JVM내의 Runtime Data Areas에 바이트 코드를 배치시키고, 실행 엔진에 의해서 바이트 코드가 기계어로 변환된다. 실행 엔진의 종류에는 인터리프터와 JIT가 있다.

Garbage Collector
힙 메모리 영역에 생성된 객체들 중 더 이상 사용하지 않는 객체들을 제거하는 역할이다.
(참조되지않은 객체)

Runtime Data Area: 프로그램을 수행하기 위해 OS로부터 할당받는 메모리 공간으로써 크게 5가지 영역으로 구분된다.

  • Method Area: Constant pool과 필드 정보, 메서드 정보 등 클래스와 인터페이스에 관련된 정보가 저장되는 영역
  • Heap Area: 인스턴스 변수가 생성되는 공간으로 프로그램 실행 중 생성되는 인스턴스는 모두 이 곳에 저장된다.
  • Stack Area: 메서드가 호출되면 스택에 메서드를 위한 메모리가 할당되며, 메소드가 작업을 수행하는 동안 지역변수, 매개변수, 리턴 값등을 저장하기 위해 사용된다.
  • PC Register: 스레드가 시작될 때마다 생성되는 영역으로 스레드마다 하나씩 가지고 있다. 현재 스레드가 실행되는 부분의 주소와 명령을 저장하고 있어 이것을 이용해 스레드를 돌아가면서 수행한다.
  • Native Method Stack: 자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역이다.

JDK와 JRE의 차이

학습 전

이거는 마인크래프트 했던 짬밥으로 알고있다. JDK와 JRE의 차이는 개발 프로그램 유무이다.
JRE는 자바를 실행하는 용이고, JDK는 자바를 실행하고, 컴파일, 빌드하는 용도이다.

학습 후

굿

profile
블로그 이사갔어요 https://kiseoky.tistory.com

0개의 댓글