Java Virtual Machine 의 약자. Java 언어로 작성된 프로그램이 돌아갈 수 있는 가상 머신을 의미한다. 그 자체로 하나의 컴퓨터 처럼 동작한다. 내부적으로 thread 자원을 관리하고, 메모리도 주어진 메모리 안에서 알아서 관리한다.
JVM이 이해할 수 있는 machine instrcution으로 구성된 class파일 (java 코드를 컴파일해서 생성)을 읽어서 실행한다.
이미지 출처 : https://medium.com/@PrayagBhakar/lesson-2-behind-the-scenes-4df6a461f31f
class 파일에 실제로 JVM이 읽을 수 있는 머신 인스트럭션이 있다. 그 머신 인스트럭션을 JVM이 해독해서 운영체제에 맞는 실제 기계 코드에 호환되게 돌아가게 해준다.
이미지 출처 : https://notes.dmitriydubson.com/compilers/java-compile-process/
좀 더 정확하게 보면 자바 소스 파일로 .클래스 파일이 만들어질 때는 컴파일 타임이 되고 실제 실행할 때 런타임. 우리가 프로세스를 실행한다는 건 런타임이다. 런타임에는 .class 파일을 JIT(JVM Just-in-time Compiler) 컴파일러 저스틴 컴파일러라고 하는 코드가 들어온 대로 즉시즉시 실행할 수 있는 컴파일러다.
JIT 컴파일러가 즉시즉시 .class 파일을 읽어서 머신 인스트럭션을 네이티브의 인스트럭션으로 바꿔서 실행을 해준다.
오래전 High Level Language 종류가 얼마 없었을 때, Java는 write once, run everywhere 로 큰 인기를 끌었다. 그동안 주로 사용되던 C, C++ 에서 가장 어려운 문제가 memory 관리인데,
왜냐면 이 친구들은 자기가 malloc, dealloc 이런 걸 호출해줘야 되는데 실제로 우리가 코드 한 줄로 쭉 이어쓰진 않는다. 그리고 C++되면 오브젝트 오리엔티드 프로그래밍이라고 해서 여러 개의 클래스나 객체에서 컨텍스트 왔다 갔다 하는데 록, 디얼록 한 위치를 잘 찾을 수가 없었다. 그래서 메모리가 할달되었는데 해제를 못 하면 계속 점유하고 있는 게 된다. 그리고 메모리가 점유하지 않았는데 아니면 이미 디얼록이 됐는데 또 해젷려고 하면 그 때 메모리 참조가 발생해서 프로그램이 죽는다. 그래서 이런 메모리 관리를 하는데 굉장히 시간이 많이 들었다. 디버깅도 어렵고. 그래서 큰 프로그램을 만들 때, 사이드 이펙트가 너무 많으니까 관리가 어려운 게 있었는데, 자바는 위에 있는 아키텍쳐 특성 상 자바 코드를 한 번 쓰면 어떤 머신에서나 돌리고 그러면 하드웨어마다 메모리 관리를 하는데 이걸 신경 쓰지 않고 코딩할 수 있는 건 GC가 있기 때문에 이런 걸 신경 쓰지 안혹 코딩할 수 있었다. 그리고 C랑 C++에서는 각 컴퓨터별로 빌드를 따로 해야 했다. (multi build) 자바 같은 경우는 한 번만 컴파일 하면 그걸를 어떤 하드웨어를 쓰던지 아니면 어떤 CPU 칩을 쓰던지 상관 없이 호환하는 작업은 JVM 개발자가 미리 해 놓은 것이다. 그래서 자바가 읽을 수 있는 클래스 파일만 놔두면 그 클래스파일을 읽어서 어떤 운영체제를 실행할지는 JVM에 이미 다 IF else 처리 이런 게 다 되어 있으니까 신경쓰지 않아도 되고, 굉장이 개발 속도가 빨라진다. 그리고 디버깅 시간도 적어지니까 개발 난이도도 낮아지고
이것을 신경쓰지 않고 코딩할 수 있었기 때문이다.
따라서 오랜기간 안정성이 중요하고, 복잡도가 높은 시스템은 Java로 많이 개발되어 왔다.
물론 단점도 있다. 어쨋든 두 번 컴파일한 결과를 JIT
C는 빌드의 결과물이 바로 네이티브 인스트럭션인데
자바의 결과물은 .class 파일이고 이게 네이티브 인스트럭션으로 바뀌는 건 런타임에서 수행하니까 조금 더 시간이 걸릴 수 밖에 없다. 속도가 중요하면 C로 개발, 안정성이 중요하면 Java로 개발했다.
Java가 인기를 끌면서 JVM도 시간이 지날수록 성숙해져서 속도도 빠르고, 메모리 관리도 잘하게 되었다.
30년 가까이 쌓여온 여러 운영체제와의 호환성 및 버그 수정의 이력이 JVM의 가장 강점이다.
JVM은 class 파일로 된 jvm machine instruction을 해석해서 동작한다는 것에 착안해서, Java 언어의 한계를 극복하고자 문법이 더 좋게 만들어진 언어들도, 그 결과물을 class 파일로 만들어 JVM에서 동작할 수 있도록 했다.
그래서 Java 언어의 한계는 뛰어넘고, JVM의 안정성은 취하는 전략으로 만들어진 언들로 인해 JVM은 더 다양한 분야에서 사용되게 되었다.
이러한 언어들로는 Groovy, Scala, Kotlin 등이 있다.
결국에는 어떤 언어의 컴파일. (컴파일은 자바 컴파일러가 아니어도 되는 것)의 결과가 .class 파일이기만 하면 .class에 들어갈 수 있는 인스트럭션이기만 하면 이 친구는 JVM에서 돌아갈 수 있다. 아 나는 새로운 언어랑 컴파일러만 만들어야겠다. 그러면 JVM의 안정성이라는 장점을 가져갈 수 있으니까. 그런 전략으로 만들어진 언어들이 스칼라, 코틀린, 그루비 등이 있다.
스칼라는 펑셔널 프로그래밍이 가장 직관적이고 오류도 없고, 완결성을 가지는 좋은 프로그래밍이다.
코틀린은 가장 실용적인 문법을 가져다가 스칼라나 그루비, 자바에 있던 장점들만 가져온, 그리고 이상한 부분들은 버린 언어.
2000년대 후반부터 Single Machine의 한계를 극복하고자 개발된 많은 오픈소스들은 Java을 주 언어로 개발이 되었다.
현재 빅데이터분야에서 가장 많이 사용되는 Hadoop이 Java 로 만들어졌다.
그렇다보니 안정성있는 클라이언트 라이브러리도 Java로 만들어진 것이 가장 먼저 나오고, 가장 성숙했다.
한동안은 Hadoop을 쓰려면 Java 로 개발을 해야했다.
뿐만 아니라 Hadoop과 궁합이 좋은 리소스 매니저 Yarn의 역할도 컸다.
Yarn 또한 Java로 구현되어있어서 client API가 Java위주로 개발되었다.
따라서 Hadoop을 이용하는 대용량 분산처리 어플리케이션, 프레임워크들 또한 JVM에서 구동되는 언어들을 먼저 선택할 수 밖에 없었다.
하둡이랑 궁합이 좋은 리소스 매니저
그러니까, 하둡이 어차피 대량의 컴퓨터를 점유하고 있으니까. 거기스 리소스 매니저가
파일시스템은 하둡을 쓰고, 여러가지 프로세스를 돌리고 종료할 수 있게 하는
리소스 매니저 Yarn이라는 친구가 있는데 이 친구한테 띄우면 하둡 파일 시스템의 로컬리티 ,(내가 원하는 파일이 있는 위치에 내 프로세스가 떠서 잘 돌게 한다. ) 같은 것들을 할 수 있어서 Yarn도 자바로 구현되고, 하둡을 이용하는 대용량 분산처리 어플리케이션 그리고 프레임워크들이 JVM에서 구동되는 언어들을 먼서 선택할 수 밖에 없다 .왜냐면 처음에 파이오니어들은 하둡에서 돌아가는 친구를 알려면 하둡을 이해해야한다. 그런데 하둡을 이해하려면 자바 코드를 읽어야 한다. 그래서 JVM에서 구동되는 녀석들을 선택할 수 밖에 없었다.
Java
Scala
위와 같은 도구들이 Java 또는 JVM호환 언어로 개발되었다보니, 가장 먼저 지원되는 Client 라이브러리도 Java Client 일 수 밖에 없다.
따라서 신기술을 빠르게 적용하는 사람들이 Java 로 개발할 수 밖에 없었던 것이다.
Golang 은 쉽고 확장성 있는 문법으로 누구나 다양한 프로그램을 개발할 수 있다.
빌드 또한 운영체제의 native library에 종속되지 않고 할 수 있다.
또한 메모리 관리를 자동으로 하는데도 포인터를 직접 쓸 수 있어서 고성능 어플리케이션을 만들 때 또한 좋다.
그런데 왜 Golang으로 만들어진 데이터 엔지니어링 도구는 별로 없는 것일까?
C, C++의 대체자 Rust. C 처럼 쉽고, C++ 보다는 복잡하지 않은, 그리고 C수준의 고성능 개발이 가능하다.
손쉬운 메모리 관리와 유연한 타입시스템. 게다가 빌드 결과물이 WASM으로 나오면 확장성까지 있다.
이제 고성능 데이터베이스는 Rust로 만들어야 하는 것 아닐까? 왜 분산 데이터베이스들은 다 Java로 만들어졌을까?
다음의 상황이 생길 경우, JVM과 그 기반언어가 데이터엔지니어링에서 가지는 지배력은 약해질 수도 있다.
사실상 기업용에서 대용량 분산 파일 저장 시스템을 쓴다, 대용량 분산된 리소스 풀을 만들어 놓고 거기서 누구든지 원하는 작업을 얻었다 제출했다 하고싶으면 지금 무조건 선택되는 건 하둡이다.