Back-end/Java

다시 하자 기초! 자바 동작과정, 자바의 컴파일러

이안_ian 2019. 4. 16. 17:00
반응형

자바의 동작과정

Hello.java -> javac.exe(자바 컴파일러) -> Hello.class 생성 -> java.exe(자바 인터프리터) -> “Hello world” 출력

 

컴파일러란?

원시 언어에서 목적 언어로 바꾸는 작업으로 A라는 언어에서 B라는 언어로 통역해주는 작업이다. 프로그래밍에서는 주로 고급언어를 기계어로 바꿔주는 것을 말한다. 근데 C나 C++의 경우 컴파일러는 CPU나 운영체제마다 가지고 있는 기계어가 조금씩 다르기 때문에 CPU나 운영체제마다 별도의 컴파일러가 필요하다. 같은 고급언어로 작성한 코드라도 다른 기계어 코드를 생성해야하는 것이다.

 

하지만 자바에선 컴파일러가 기계어로 바꾸는 것이 아니라 '바이트 코드로'라는 것으로 변환 시킨다. 

자바의 가장 큰 장점은 JVM이다.

자바로 코드를 작성하면 자바 컴파일러가 *.class(바이트 코드) 파일을 만들어주고 JVM에서 운영체제(Window, Linux)에 맞는 형태로 변환 해주기 때문이다. 그렇기 때문에 자바로 작성된 코드는 운영체제에 독립적이다. 하지만 JVM은 운영체제에 종속적이기 때문에 해당하는 OS에 맞는 JVM 설정을 해줘야한다. 하지만 이건 우리가 하는게 아니기에 패스~

 

JVM의 구성요소

1.자바 인터프리터

2.클래스 로더

3.JIT 컴파일러

4.가비지 컬렉터

 

인터프리터와 클래스 로더

자바 컴파일러에 의해 변환된 자바 바이트 코드를 읽고 해석하는 것이 자바 인터프리터이다. 자바는 동적으로 클래스를 읽어오므로, 프로그램이 실행중인 런타임에서야 모든 코드가 자바 가상머신과 연결됩니다.

이렇게 동적으로 클래스를 로딩해주는 것이 클래스 로더입니다.


JIT (Just In Time) Compiler
Interpreter 방식의 단점을 보완하기 위해 도입된 방식으로,
Interpreter 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일 하여 네이티브 코드로 변경하고,
더 이상 Interpreting 하지 않고 네이티브 코드로 직접 실행하는 방식이다.
네이티브 코드는 캐시에 보관되기 때문에 한 번 컴파일된 코드는 빠르게 실행할 수 있다.
물론 한 번만 실행되는 코드라면 JIT 보다 Interpreter 방식이 유리하다.
따라서 JVM은 해당 메소드가 얼마나 자주 수행되는지 체크하고, 일정 정도를 넘을 때 컴파일을 수행한다.

 

가비지 컬렉터

가비지 컬렉터를 이용하면 사용하지 않은 메모리를 자동으로 회수해준다. 메모리를 관리를 알아서 해주니 개발자는 더욱 손쉽게 프로그래밍을 할 수 있게 도와준다.

 

컴파일러 vs 인터프리터

컴파일러 - 고급언어로 쓰여진 프로그램이 컴퓨터가 이해할 수 있는 기계어로 바꿔준다. 번역과 실행 과정을 거쳐야 하기에 번역과정이 번거롭고 시간이 오래 걸리지만, 한번 번역하면 이후엔 다시 번역하지 않으므로 실행속도 빠름

 

인터프리터 - 한 단계씩 기계어로 해석하여 실행하는 언어처리 프로그램이다. 줄 단위로 번역, 실행되기 때문에 시분할 시스템에 유용하며 원시 프로그램의 변화에 대한 반응이 빠릅니다. 한 단계씩 테스트와 수정을 하면서 진행시켜 나가기 때문에 대화형 언어에 적합하지만 실행 시간이 길어 속도가 늦다는 단점이 있고 목적프로그램이 생성되지 않는다.

 

자바 사용시 유의해야 할 부분

자바에서 모든 코드는 반드시 클래스 안에 존재해야 하며, 서로 관련된 코드들을 그룹으로 나누어 별도의 클래스를 구성하게 된다. 그리고 이 클래스들이 모여 하나의 Java 애플리케이션을 이룬다. 클래스를 작성하는 방법은 간단하다. 키워드 ‘class’ 다음에 클래스의 이름을 적고, 클래스의 시작과 끝을 의미하는 괄호 {안에 원하는 코드를 넣으면 된다.

 

public static void main(String[ ] args)main메서드의 선언부인데, 프로그램을 실행할 때 java.exe에 의해 호출될 수 있도록 미리 약속된 부분이므로 항상 똑같이 적어줘야한다.

모든 클래스가 main을 가지고 있어야할 필요는 없지만 하나의 java 애플리케이션 안에 하나는 반드시 필요하다. 그래야 애플리케이션이 실행이 되기 때문이다.

 

하나의 소스파일에 하나의 클래스만을 정의하는 것이 보통이지만, 하나의 소스파일에 둘 이상의 클래스를 정의하는 것도 가능하다. 이 때 주의해야 할 점은 소스파일의 이름은 public class의 이름과 일치해야한다.’는 것이다. 만일 소스파일 내에 public class가 없다면, 소스파일의 이름은 소스파일 내의 어떤 클래스의 이름으로 해도 상관없다.

 

자주 발생하는 에러와 해결 방법

cannot find symbol 또는 cannot resolve symbol

지정된 변수가 메서드를 찾을 수 없다는 뜻으로 선언되지 않은 변수나 메소드를 사용한 것

 

‘;’ expected

필요한곳에 세미콜론이 없다는 뜻이다.

 

Exception in thread “main” java.lang.NoSuchMethodError: main

main 메서드를 찾을 수 없다는 뜻이다. 혹시 main함수 부분에 오타가 없는지 찾아보자

 

Exception in thread “main” java.lang.NoClassDefFoundError: Hello

Hello라는 클래스를 찾을 수 없다는 뜻으로 클래스 ‘Hello’의 철자 특히 대소문자를 확인해보자, 이상이 없다면 클래스 파일(*.class)이 생성되었는지 확인한다. 그 담엔 classpath확인

 

illegal start of expression

문장의 앞부분이 문법에 맞지 않다는 뜻으로 문장에 문법적인 오류가 있다는 에러다. ( { 의 괄호를 닫지 않는 듯 문법의 형식이 맞지 않다는 뜻이다.

 

 

 

 

 

반응형