IT/Java

[JAVA 스터디][1주차_2] javac 컴파일 및 실행, JIT컴파일러 정리

jaewon_sss 2020. 11. 16. 00:53
반응형



1주차(1)에 이어서...

1주차(2) - 목차


5. 컴파일 하는 방법
6. 실행하는 방법
7. JIT 컴파일러란 무엇이며 어떻게 동작하는지




먼저, 컴파일이 무엇인지에 대해 알아보겠습니다.



인터프리터와 컴파일러

  인터프리터는 사용자가 작성한 소스코드를 '한 문장씩 읽고' 바로 기계어로 바꿔줍니다. 그 후에 변환된 코드를 실행합니다. 그러나 컴파일러는 '전체 소스코드를 모두' 기계어 파일로 바꿔주고 그 후에 변환된 코드를 실행합니다. 빌드 시, 인터프리터는 큰 일을 하지 않지만 컴파일러는 기계어 소스 코드를 기계어 파일로 생성하기 때문에 오래 걸리는 것처럼 보일 수 있습니다. 그러나 그 이후 실행에서, 인터프리터는 한 줄씩 읽고 기계어로 변환하여 실행하지만 컴파일러는 만들어둔 실행파일만 읽으면 되므로 실행속도에서 더 빠릅니다. 

인퍼트리터 언어의 예로 python, php 등이 있고 컴파일러 언어의 예로 C, C++, java 등이 있습니다.



그렇다면 자바는 어떻게 컴파일을 할까?

5. 컴파일 하는 방법



1. Java에서 소스를 작성하면 Java Source 생성됩니다.

2. Java Compiler인 javac를 통해 Java Byte Code를 생성합니다.

3. Java Compiler인 javac 를 통해 생성된 자바 바이트 코드(.class)는 Class Loader에 의해서 JVM내로 로드됩니다.

4. 메모리에 로드된 클래스(Java Byte Code)들을 Excecution Engine를 통해 기계어로 변경하여 메모리 상(Runtime Data Area)에 배치합니다. 명령어를 하나 하나 실행하는 인터프리터(Interpreter)방식이 있고 JIT(Just-In-Time) 컴파일러를 이용하는 방식이 있다.

5. Garbage Collector(GC)는 Heap 메모리 영역에 생성(적재)된 객체들 중에 참조되지 않는 객체들을 탐색 후 제거하는 역할을 합니다.



6. 컴파일 하는 방법과 javac 옵션


Java Byte Code(.class 파일)을 JRE의 java 프로그램으로 실행을 시키면 끝(.java 는 실행 안됨!!)


그럼 Java Byte Code를 만들기 위한 javac의 옵션을 알아보자

사용법: javac <options> <souce files>
예를들어, Hello.java, Greeting.java 두개의 파일이 존재한다면,
javac Hello.java Greeting.java
javac *.java (*을 사용해서, 모든 확장자가 .java인 파일을 컴파일할수 있다.)

1) 옵션:

a) -classpath:
-classpath(cp) path(파일 절대 경로):
컴파일러가 컴파일 하기 위해서 필요로 하는 참조할 클래스 파일들을 찾기 위해서 컴파일시 파일 경로를 지정해주는옵션.

예를 들어,  Hello.java파일이 C:\Java 디렉터리에 존재하고, 필요한 클래스 파일들이 C:\Java\Engclasses에 위치한다면, javac -classpath C:\Java\Engclasses C:\Java\Hello.java 로 해주면 된다.

만약 참조할 클래스 파일들이 C:\Java\Engclasses외의 다른 디렉터리에도 존재한다면, C:\Java\Korclasses 일경우, javac -classpath C:\Java\Engclasses;C;\Java\Korclasses C:\Java\Hello.java

그리고, 현재 디렉토리역시 포함하고 싶다면, javac -classpath .;C:\Java\Engclasses;C;\Java\Korclasses C:\Java\Hello.java 기본적으로, dos에서는 .는 현재 디렉터리를 의미하고, ..는 현재 디렉터리의 상위디렉터리를 의미한다.

또한 classpath 대신 단축어인 cp를 사용해도 된다.
javac -cp C:\Java\Engclasses C:\Java\Hello.java

b) -d:
-d directory
클래스 파일을 생성할 루트 디렉터리를 지정합니다.
기본적으로 컴파일러는 -d옵션을 주지 않으면, 소스파일이 위치한 디렉터리에 클래스 파일을 생성시킵니다.
예를 들어,  Hello.java파일이 C:\Java 디렉터리에 존재하고 클래스 파일의 루트디렉터리를 C:\Java\Classfiles라고 하면,
javac -d C:\Java\Classfiles C:\Java\Hello.java 입니다.

만약 -d 옵션을 사용하려고 하는데, 루트디렉터리(위예에서는 C:\Java\Classfiles) 가 존재 하지 않는다면,
“The system cannot find the path specified”라는 에러 메시지를 보게 됩니다.
현재 작업 디렉터리가 C:\Java\Classfiles 에 위치하면,
javac -d .\Classfiles Hello.java 와 같이 상대 디렉터리로 표현할수 있습니다.

c) -encoding:
-encoding encoding name
소스 파일에 사용된 문자열 인코딩을 설정합니다.
만약 위옵션이 설정되어 있지 않으면, 플래폼의 기본적인 컨버터가 사용되어 집니다.

d) -g:
모든 디버깅 정보를 생성시킵니다.
만약 위옵션이 설정되어 있지 않으면, 기본적으로, 라인넘버만 생성시킵니다.
-g:none: 디버깅 정보를 전혀 생성 시키지 않습니다.
-g:{lines, vars, source}:
위처럼 명시적으로, 몇몇 디버깅 정보를 생성시킬수 있습니다.
lines은 라인정보, vars는 지역변수, sounce는 소스 파일 정보를 나타냅니다.

e) -nowarn:

경고 메시지 (warning message)를 생성시키지 않습니다.


f) -verbose:

컴파일러와 링커가 현재 어느 소스파일이 컴파일되고 있고, 어느 파일이 링크되고 있는지
그정보를 출력한다.


h) -deprecation:

소스 코드내에서, 사용되어진 deprecated API의 위치 를 출력 합니다.

ex)
C:\Java> javac World.java
Note: World.java uses a deprecated API. Recompile with “-deprecation” for details
.
1 warning
C:\Java> javac -deprecation World.java
World.java:52: Note: The method java.awt.Dimension size() in class java.awt.Compon
ent has been deprecated.
Dimension d = size();

Note: World.java uses a deprecated API. Please consult the documentation for a be
tter alternative.

i) -sourcepath:

-sourcepath 소스패스

소스파일의 위치를 지정합니다.

j) -target:

-target 자바버젼

지정된 자바버젼의 VM에서 작동 되어지도록 클래스파일을 생성 시킵니다.

1.1
jvm 1.1 버젼에서 호환되어질수 있는 클래스 파일생성
1.2
jvm 1.2 버젼에서 호환되어질수 있는 클래스 파일생성
1.3
jvm 1.3 버젼에서 호환되어질수 있는 클래스 파일 생성

ex)
javac -target 1.2 Helloworld.java

k) -bootclasspath 패스:

특정한 bootstrap또는 확장 클래스를 지정할수 있다.
기본적으로, 자바컴파일러는 javac(컴파일러명령)이 설치된 플래폼의 bootstrap과 확장클래스들을 통해서, 컴파일작업을 수행하지만, bootclasspath 옵션을 사용하면, cross-compiling이라고 해서, 다른 자바플래폼의 bootstrap과 확장클래스들을 통해서, 컴파일 할수 있는 기능을 지원한다.

예를들어,
javac -target 1.1 -bootclasspath jdk1.1.7/lib/classes.zip -extdirs “” OldCode.java
컴파일러에게 현재 자신의 bootstrap을 사용하지 말고, jdk1.1.7/lib/classes.zip bootstrap클래스들을 사용해서 컴파일 하라고 명령하는것이다.

참고로, 모바일자바에서, 모바일폰에 설정된, jvm에 맞도록, 소스코드를 컴파일하기 위해서, 주로 사용되어지는 옵션이다.

l) -extdirs 디렉터리:
특정한, 확장 디렉토리를 지정한다.cross-compiling시 주로, 사용되어지는 옵션이면, 각디렉터리들은 콜론(:)에 의해서, 분리되어진다.
컴파일시, 기술한 디렉터리의 클래스 파일을 참조한다.

참고) http://sjava.net/2008/02/javac-%EB%AA%85%EB%A0%B9%EC%96%B4%EC%9D%98-%EC%98%B5%EC%85%98-%EC%A0%95%EB%A6%AC/

7. JIT 컴파일러


메모리에 로드된 클래스(Java Byte Code)들을 Excecution Engine를 통해 기계어로 변경하여 메모리 상(Runtime Data Area)에 배치합니다. 

명령어를 하나 하나 실행하는 인터프리터(Interpreter)방식이 있고 JIT(Just-In-Time) 컴파일러를 이용하는 방식이 있습니다.
Interpreter는 바이트 코드를 한줄씩 읽기 때문에 실행이 느린 단점이 있었습니다. 



이러한 단점을 보완하기 위해 나온 것이 JIT Compiler 입니다. 




인터프리터 방식으로 실행을 하다가 적절한 시점에 바이트 코드 전체를 컴파일 하고 더이상 인터프리팅 하지않고 해당 코드를 직접 실행 하는 것 입니다. JIT Compiler에 의해 해석된 코드는 캐시에 보관하기 때문에 한 번 컴파일 된 후에는 빠르게 수행하는 장점이 있습니다. 하지만 인터프리팅 방식보다는 훨씬 오래 걸리므로 한번만 실행하면 되는 코드는 인터프리팅 하는 것이 유리합니다.


반응형