[Java] 자바(Java) 언어의 특징
-플랫폼 독립적이다 (Platform Independent)
플랫폼이란? 운영체제 + 하드웨어를 말함
플랫폼 독립적이라는 것의 의미는 한 번 짠 그 코드는 이 컴퓨터에서도 돌아가고 운영체제와 CPU와 전혀 상관없이 다른 컴퓨터에서도 똑같이 잘 돌아간다는 것을 의미한다. CPU와 운영체제가 서로 다른 컴퓨터에서도 말이다.
따라서 플랫폼 종속적인 프로그래밍 언어들은 운영체제에 따라, 하드웨어(CPU)에 따라서는 그 코드가 돌아가지 않을 수도 있다는 불편함이 있다. 이것을 이식성(portability)이 낮다고 말한다. (이식성이 높은 프로그램은 이 컴퓨터에서도, 저 컴퓨터에서도 잘 돌아가는 것을 말한다.)
①하드웨어에 따라 왜 다르냐?
하드웨어 아키텍처마다 사용하는 기계어 종류가 다름. ex) 인텔 CPU와 AMD CPU는 사용하는 기계어가 다름.
그런데 실행코드는 기계어로 되어 있음. 기계(CPU)에게 일을 시켜야 하는데 CPU는 기계어 밖에 못 알아들으니까.
따라서 당연히 다를 수밖에 없음
②운영체제에 따라 왜 다르냐?
②-⑴운영체제가 사용하는 API 형식이 다름.
API(Application Programming Interface)란? 응용프로그램이 운영체제의 기능을 사용하고 싶을 때 (운영체제에게 일을 시키고 싶을 때) 프로그래밍 언어를 통해서 운영체제에게 특정 기능을 요청할 수 있는 함수라고 할 수 있음.
응용프로그램도 운영체제가 제공하는 API 함수를 이용해서 간접적으로 하드웨어에 접근할 수 있는거임. 운영체제만이 하드웨어를 직접 제어하기 때문.
따라서 컴퓨터 하나는 운영체제가 리눅스이고 또 다른 하나는 윈도우즈라면 당연히 운영체제가 제공하는 API 형식이 다르므로 프로그램에서 사용하는 함수 이름이 달라지고 (운영체제가 달라도 API 함수 이름이 같으면 상관없겠지만.) 코드도 달라질 수밖에 없다.
②-⑵운영체제마다 메모리를 관리하는 기법이 다름.
프로그램을 실행하려면 운영체제는 메모리(메인메모리, RAM)를 사용하게 되는데 운영체제마다 메모리를 관리하는 기법이 다르다.
이러한 이유들 때문에 대부분의 프로그래밍 언어들은 플랫폼 종속적인 것이다. 그러나 자바는 그렇지 않다.
자바 프로그램을 자바 컴파일러가 컴파일 하면 바이트코드가 만들어지는데 이 바이트코드는 자바 플랫폼(JVM)에서 돌아간다.
여기서 헷갈리지 말아야 할 것은 '자바 플랫폼'은 플랫폼 '종속적'이다. 따라서 실제로 오라클 홈페이지에서 JDK를 다운받을 때에 mac OS용, Windows용, Linux용이 따로 있다. 하지만 이렇게 플랫폼 종속적인 JVM만 설치되어 있으면 자바 프로그램은 플랫폼 독립적이다. (JVM도 사실상 운영체제라고 볼 수 있다. 메모리를 관리하는 능력이 있기 때문) Windows용이든 mac OS용이든 Linux용이든 자바 플랫폼 위에서는 똑같은 코드가 멀쩡히 다 돌아갈 수 있는 것이다.
-C/C++ vs Java
①실행 환경
C/C++ 프로그램을 작성하여 컴파일러를 통해서 목적코드가 만들어지면 목적코드 안에 printf나 cout 같은 함수가 있을 수 있다. 그런데 이러한 함수는 내가 만든 함수가 아니다. 따라서 이 함수 호출 부분을 라이브러리 안에 있는 함수와 연결시켜줘야 하는데 그것을 링크(link)라고 한다. C/C++의 경우 프로그램 실행 전에 링크를 하므로 정적인 링킹(static linkng)이다. 그 후 운영체제 위에서 프로그램이 돌아갈 때 printf나 cout 같은 함수들이 링크되어있기 때문에 그 함수가 있는 라이브러리가 프로그램 안에 포함되어 있는 것이다. 따라서 자연히 프로그램의 크기도 커지게 된다.
그러나 자바는 다르다. 자바는 정적인 링킹이 아니라 동적인 로딩을 한다.
자바는 자바 컴파일러가 바이트코드로 만들면(컴파일 방식) 링크 과정 없이 그 바이트 코드를 JVM에서 바로 실행한다. (인터프리터 방식으로) 그 프로그램을 실행하는 동안에 printf 메소드가 필요하다면 JVM의 클래스로더가 그 때 링크를 시켜주는 것이다. 필요할 때에 가져오고 반납하고 하는 것이다. 실행 도중에. 그렇다고 자바 프로그램의 크기가 작은 것은 아니다. 방식이 달라서 크기 비교는 어렵다.
②메모리 관리 기법
C/C++에서는 응용프로그램에서 메모리가 필요하면 함수를 사용해 메모리를 직접 할당할 수 있다. C에서의 malloc 함수, C++에서의 new 함수가 그것이다. 운영체제의 도움을 받아서 프로그램에서 필요한 만큼의 메모리를 할당받는 것이다.
참고로 운영체제의 가장 큰 역할은 자원 관리자(resource manager)이다. CPU, 메모리 등의 자원을 관리하는 것이다.
따라서 C 프로그램에서 이만큼의 메모리가 필요하니까 메모리를 할당해달라고 운영체제에게 요청을 하면 운영체제가 메모리에 여유가 있는지 확인하고 여유가 있다면 그만큼의 메모리를 할당해준다. 그러면 그 할당 받은 메모리를 사용해서 프로그램이 실행되는 것이다. 또한 그렇게 할당받은 메모리를 다 사용했다면 C에서는 free 함수, C++에서는 delete 함수를 호출하여 운영체제에게 자원을 반납해야 한다.
그러나 자바는 그렇지 않다. 자바 프로그램은 JVM 위에서 돌아가는데 JVM은 운영체제로부터 메모리를 미리 할당받아 놓고 자기가 관리를 한다. 따라서 자바에서 new 함수를 호출하면 운영체제의 도움이 아니라 JVM의 도움으로 메모리를 할당받아서 사용하는 것이다. 그런데 여기서 또 하나 C/C++과 다른 점이 있다.
자바에는 new 함수는 있지만 free(또는 delete) 함수는 없다는 것이다. 자바에는 가비지 컬렉터(Garbage Collector)가 있기 때문에 알아서 다 쓰고 난 메모리 자원을 수거한다. 따라서 자바에서는 메모리 누수 걱정을 하지 않아도 된다는 장점이 있다. 하지만 가비지 컬렉터가 가비지를 모으려고 돌아다니면 그 때 프로그램의 속도가 느려질 수 있다는 단점도 있다. 그래서 JDK 11부터는 속도를 개선시키기 위해서 ZGC(A Scalable Low-Latency Garbage Collector)라는 새로운 가비지 컬렉터를 사용한다. (약자가 왜 ZGC냐면 처음에는 Zero Latency Garbage Collector로 하려고 했으나 현실적으로 Zero Latency는 불가능하기 때문에 약자는 ZGC이지만 풀이는 다르다고 한다.)