출처: http://loveinsky.tistory.com/entry/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-1-2


앞에서 JAVA 에 대한 개략적인 특징들을 알아보았다. 그 개략적인 특징들을 중심으로 이제부터는 JAVA 의 세심한 부분에서의 특징들을 분석할 것인데, 우선 첫번째로 JAVA Development 과정을 알아볼 것이다. 어떻게 작성하고, 어떤 방식으로 '소스 코드'가 해석되고, 그 해석된 코드는 어떤 방식으로 실행되는지 전반적인 과정을 이번 1 (2) 에서 알아보고, 다음 글인 2 장에서 부터는 다른 언어와 차별화를 두는 JAVA의 특성인 '객체 지향성(Object-Oriented)'의 특성들에 대해 알아보자.

 

우선 컴퓨터 언어는 3 가지 종류로 분류된다.

   저수준 언어 (Low-Level)

 

1) 기계어 (Machine Language) : 0101 와 같이 오직 컴퓨터만 이해하는 언어로 CPU에 내장된 명령들을 직접 사용하는 것으로, 수행시간이 빠르다. 기종마다 기계어가 다르기 때문에 언어의 호환성이 없다. 반면에 Java의 경우는 위에서 설명하였듯이 JVM을 이용해 '바이너리 코드'를 각 기계에 맞게 실행시켜준다. 

 

2) 어셈블리어 (Assembly Language) 단순한 언어로 기계어와 고수준 언어 중간지점 개념의 언어. 기계어와 1:1로 대응되는 기호로 이루어진 언어로 이도 기계어와 마찬가지로 언어의 호환성이 없다.

 

   고수준 언어 (High-Level)

 

3) 고수준 언어 (High-Level) - C, C++, C#, Java 등 인간이 실생활에서 사용하는 자연어와 비슷한 형태와 구조를 갖는다. 실행을 하기 위해서는 컴퓨터가 이해할 수 있는 기계어로 반드시 해석(Translate)되야하는데, Translate 하는 프로그램에는 컴파일러나 인터프리터가 사용된다.

 

   + 추가. JAVA 언어에 대한 개략적인 역사

 

- C  C++ 의 역사 : 진화 과정 : C à C++ à JAVA

 현대에는 일반적인 목적을 지닌 운영 시스템들을 위한 거의 모든 코드들은 C나 C++로 작성된다.

 

C

Originally implemented in 1972 

UNIX 운영 체제 개발 언어로 널리 알려져있다.

 

C++

An extension of C Developed by Bjarne Stroustrup in the early 1980s at Bell Laboratories

객체 지향 프로그래밍의 능력을 제공해준다.

 

 

- Java 의 역사 

 

1991

썬 마이크로시스템의 James Gosling 는 C++을 기반으로한 Java를 만들었다.

 

1993

Web이 급 성장함과 동시에, Web에서 많이 사용하는 Java가 유명해졌다.

이렇게 해서 Java 가 우선적으로 웹 애플리케이션 작성도구로 유명해졌다.

 

– 인터넷 & 웹 개발

– 모바일 애플리케이션과 운영체제 (안드로이드)

– 임베디드 소프트웨어

– 거대한 소프트웨어 (Enterprise Software)
 

 

컴파일러와 인터프리터는 무엇인가? 간단하게 설명하자면, 고수준 언어를 저수준 언어인 기계어로 바꾸어주는 것이다. 이렇게 번역된 프로그램은 0101과 같은 기계어로 구성되어있으며, 일반적으로는 Object Program (목적 프로그램 / .obj 또는 .o) 이라고 부르며, Java에서는 Class Program (클래스 프로그램 / .class) 이라고 부른다. 컴파일러와 인터프리터는 이렇게 기계어로 바꾸어주는 똑같은 목적을 지녔지만, 방법면에서는 이 두 방법을 따로 분류시킬 정도의 상이한 차이를 보인다.

 

1. 컴파일러 Compiler
- 컴파일러는 '고수준 언어'를 읽어내어 '목적 프로그램'으로 번역한 후, Linking 작업을 통해 컴퓨터에서 실행 가능한 실행 프로그램인 ‘기계어 프로그램’을 만들어낸다. 아래 그림에서 점선 박스 안에 있는 과정이 컴파일러의 '컴파일' 과정이다.

 

Source ( 고수준언어로 작성된 소스 프로그램 ) ]

|

<Compiler (컴파일러) : Sourse를 Compile 한다.>

|

Object ( 기계어(저수준언어)로 작성된 목적 프로그램) ]

|

<Linker (링커) : Object들을 Link 한다.>

|

Execute ( 기계어들을 각자 의미에 맞게 Link시킨 최종 실행 프로그램 ) ]

 

 

 

2. 인터프리터 Interpreter

- 인터프리터는 ‘고수준 언어 프로그램’을 직접적으로 바로 실행 한다. 그렇기 때문에 목적 프로그램을 만들지 않는다.프로그램을 '인터프리트'하는 것은 그 프로그램의 ‘기계어(기계 코드) 프로그램’을 실행하는 것 보다 느리다. 아래 점선 박스 안에 있는 것이 인터프리터의 과정이다.

 

Source ( 소스 프로그램에서 '한 줄'만 ) ]

|

<Interpreter (인터프리터) : Sourse에서 '한 줄'의 고수준 언어를 Interpret 한다.>

< Object. 목적 프로그램을 거치지 않고, paser에 의해 자동 parsing 된 후 바로 실행된다. >

|

Execute* ( *작은 의미에서의 실행. 즉 '한 줄'에 대한 실행만을 뜻한다. ) ]

|

< 이 과정을 계속해서 반복한다. C 언어에서의 디버깅과 유사 >

 

인터프리터가 컴파일러에 비해 실행 속도가 느린 이유는 '기계어 프로그램'는 모든 순서 처리와 기타 다른 요소들을 다 정리한 후에 '목적 파일'이라는 하나의 통 파일로 제작된 것이기 때문이다. 기계어들이 처음부터 끝까지 정리된 상태에서 실행하는 것과, 기계어를 처음부터 끝까지 한 줄, 한 줄 해석해 나가는 것이 상식적으로 느리다. 추가적으로 컴파일러는 번역속도 면에서는 인터프리터 보다 느리다. 이유는 위와 같다. 한 줄을 번역하는 것이, 전체를 번역하는 것보다 빠른것은 당연하다.

 

 

Java 도 역시 '고수준 언어' 중 하나로, 해석 과정을 거쳐야지 비로소 실행을 할 수 있게된다.

' 그럼, Java 는 컴파일러를 사용하는 컴파일러 언어일까? 인터프리터를 이용하는 인터프리터 언어일까? '

 

 

Java 는 '고수준 언어'이기 때문에 Java 프로그램을 개발하려고 하는 프로그래머들은 어떠한 종류의 프로그램을 개발 하려고하던간에 우선 맨 처음 소스 프로그램을 Java 코드로 작성해야 한다. 이를 프로그래밍의 가장 초기 과정 Edit라 하며 컴파일러와 인터프리터의 사용은 그 다음 과정에서 사용된다. 전체 프로그래밍 과정은 아래와 같다.

 

1. Edit

2. Compile

3. Run ( Interpret )

   - Load

   - Verify

   - Execute  

 

Edit 다음 이 소스 프로그램을 기계어로 바꾸어야 한다. 위 2. 번 Compile을 보면 알 수 있듯이, 이 바꾸는 과정을 Compile 이라고 부르고 이 과정은 Compiler 를 통해 하게된다.

 

Compile 을 하면 .class 라는 확장자를 지닌 'Bytecode 프로그램'이 생겨난다. 그 다음 3. Run 과정에서는 2. Compile해서 나온 'Bytecode 프로그램'을 실행해서 원하는 결과를 출력하기 위하여, JVM 이라는 프로그램을 사용하게 된다. JVM 은 Bytecode 들을 C 언어에서와 같이 따로 Link 같은 결과를 거쳐 .exe 확장자를 가진 '실행 프로그램'과 같은 '결과 프로그램'을 만들지 않고, Bytecode 프로그램에 있는 코드 그대로 한 줄, 한 줄 씩 읽어서 Interpret 방법으로 프로그램을 직접 바로 실행한다. 한 줄 한 줄 씩 Interpret 하는 과정에서 JVM은 사용자 User 가 사용하고 있는 H/W 와 OS 들에 맞추어 Bytecode를 '맞춤 실행' 해준다. 이 '맞춤 실행'은 Java의 큰 특징이기도 하다.

 

 Compile 과정 ( 2. Compile 과정 )

Source ( Java 언어로 짜여진 소스 프로그램 ) ]

|

<Compile : 컴파일, 고수준 언어를 저수준 언어인 기계어로>

|

Class ( Source 프로그램을 기계어로 해석한 Bytecode 프로그램 ]

|

 

 

 Interpret 과정 ( 3. Run 과정 ) 

Class ( Source 프로그램을 기계어로 해석한 Bytecode 프로그램 ]

|

<Interpret : 인터프리트, Bytecode 프로그램인 Class 프로그램을 '한 줄' 단위로 실행>

|

Execute* ( *.exe 확장자와 같은 개별적인 '실행 프로그램'을 만들지 않는다. ]

이유는 .class 확장자를 지닌 Bytecode 프로그램들만 갖고,

어느 OS 든지 JVM 을 이용해 그때 그때 Interpret (즉흥적인 프로그램 실행) 을 하기 때문이다.

 

 

 

Java의 특징 중 하나인 JVM 가 수행하는 Interpret 과정( Run 과정 )은 단순하게 하나의 과정으로 보이지만, 사실은 하나의 과정속에 여러 추가 과정들이 포함되어 있다. Interpret ( Run ) 의 자세한 과정은 다음과 같다.

 

   - Load

Class loader 가 .class 파일들을 primary memory 로 load 하고, 또한 실행하려는 프로그램에 필요한 다른 .class 파일들( C 언어에서 '라이브러리' 처럼 미리 정의 되어있는 클래스들 )도 load 한다.

( 이 .class 파일들은 당신의 시스템에 있는 disk 에서 load 될 수 도있고, 네트워크를 통해서도 load 될 수 있다. )

 

   - Verify

 

.class 파일들이 load 되면, bytecode verifier 가 load 된 class 파일들의 bytecode들을 보안을 위해 검사한다.

( Java 가 서버, 클라이언트 등의 네트워크 애플리케이션에 많이 사용되기 때문에 Verify 기능을 넣었다. Java가 처음 개발될 때, 인터넷에 대한 언어로 개발했었기 때문. 위에 '파란 박스' Java의 역사 참조 )

Java 는 네트워크를 통해 전달된 Java 프로그램들이 컴퓨터, 웜 바이러스등의 이유로 당신의 시스템이나 파일들을 망가트리지 않는다는 점에 대해 강력한 보안을 확신시켜준다.


   - Execute

 

JVM 가 특정 프로그램의 bytecode들을 읽어내 실행한다. JVM 은 가장 초기 버전에는 Interpreter 로써의 역할만을 수행하였지만, 후에 여러 실행 효율에 대한 이야기가 나오자, 성능 향상을 위해 Compiler 를 추가시켰는데, 그것이 Just-In-Time Compiler 이다. 그렇게 해서 최종적으로 JVM 은 Interpreter + JIT Compiler 이들을 혼합하여 사용한다.

 

Interpret 를 수행함과 동시에 bytecode 들을 분석하면서, hot spots ( bytecodes 중에서 자주 실행하는 부분 ) 을 찾는다. hot spots 을 찾으면 JIT Compiler 가 프로그램내에서 반복 실행되는 부분에 대해서 실행중에 기계어 명령으로 변환하여 처리한다. 이런 이유로 JIT Compiler 를 Java HotSpot Compiler 라고도 부르며, bytecodes 들을 제일 컴퓨터에서 하드웨어적인 기계어(underlying computer's machine language)로 컴파일한다. ( bytecode 도 기계어로 컴파일 된 결과였다. 컴파일된 bytecode 를 한번 더 underlying computer's machine language, 아주 하위 단계의 기계어로 컴파일 하는것 ) JVM이 이렇게 가장 하위 단계의 기계어로 컴파일된 부분들을 Interpret 도중에 다시 또 다른 부분에서 맞닥뜨리게 되면, 이미 컴파일 되어있는 (가장 하위 단계의)기계어가 이 부분을 매우 빠르게 실행시켜준다. 이렇게 함으로써 '반복 처리되는 명령어들을 매 명령어 마다 반복 Interpret 해서 발생하는 커다란 비효율성'을 줄일 수 있게 된다.

 

Java 개발에서 Compiler 와 JVM 은 JDK에 포함되어있고, 이는 Oracle 홈페이지에서 언제든지 최신버전을 받을 수 있다. 이 '전체 프로그래밍 과정'을 수행하기 위해서 우리는

 

1. Edit 을 위해 메모장을 사용하고,

2. Compile 을 위한 JDK 를 다운받아서 DOS-MS (cmd.exe) 내에서 컴파일을 수행하고,

3. JDK 에 포함되어있는 JVM 을 이용하여 컴파일되어 새로 생긴 Bytecode 들을 실행해야한다.

 

이렇게 3 가지 과정을 순서대로 각자 수행하기에는 귀찮은 것이 사실이다. 이 과정들을 하나의 프로그램에서 간편하게 처리할 수 있게 해주기 위해, 예전 C 언어의 등장에서 부터 사람들이 쉽게 개발을 할 수 있게 도와주는 많은 '통합 Tool' 들이 많이 존재해 왔다. 에디터, 컴파일러, 실행기, 디버거 등의 개발에 필요한 모든 환경들을 하나로 모아준 것을 Integrated Development Environments (통합 개발 환경, IDEs) 이라고 부른다. 필자가 어렸을 때 읽었던 '터보 C'책에 나온 '터보 C' 라는것도 이 IDE 이며, 현재 사람들이 많이들 사용하는 Visual Studio 등의 Visual 시리즈들도 이 IDE 이다. Java는 현재 시중에 나와 있는 많은 언어 IDE 와는 달리 free IDE 인 Eclipse 가 존재한다. 무료임에도 매우 강력한 환경을 제공해 주기에 사람들이 많이 애용하고, 앞으로 작성할 모든 Java 관련 포스트도 다 Eclipse 를 기반으로 할 것이다.  

 

다음은 JAVA 의 가장 중요한 특징인 객체 지향성 에 대해 살펴볼 것이다. Class 에 대한 내용은 단순히 객체 개념 에서 끝나는 것이 아니라 그에 관련된 기타 다른 내용들도 많기 때문에, 1 장 처럼 2장 - (1), (2) 이런 식으로 나누어서 설명할 생각이다.

'Programing > Java' 카테고리의 다른 글

Effective Java - Reference  (0) 2016.02.29
Garbage Collection  (0) 2015.11.15
Wrapper클래스,박싱(boxing),언박싱(unboxing)  (0) 2015.11.15
Collection  (0) 2015.11.15
JVM, JRE, JDK의 차이  (0) 2015.10.11

+ Recent posts