Java Virtual Machine, Java Byte Code를 실행하는 주체이라고 정의되어 있어. 그 외에도 블라 블라 블라...

 "Java Virtual Machine은 또 뭐고, Byte Code는 또 뭐야?", "지금 껏 많이 들어왔으니깐, 그냥 진보된 기술들 중 하나인 거는 알겠어 그래서 뭐?" 이거 니 생각보다 대단한 물건이야. 자바 이전의 언어들은 왜 이런 생각을 안했는 지 바보같다고 느껴질 정도야.

 

 가비지 컬렉션

 자바 가상 머신, 즉 JVM은 굉장히 신기해. 나는 특히 JVM 중 가비지 컬렉션이 좋아. 매력있거든, 작년에 C로 자료구조를 공부할 때, 수동으로 메모리를 관리했을 때는 미치는 줄 알았는데, 가비지 컬렉션은 필요없는 건 알아서 버려줘, 메모리 누수 걱정 따윈 없애버리지. 난 가비지 컬렉션 없으면 못 살 정도야!

 

플랫폼 독립성 보장

 JVM은 운영 체제든 하드웨어든 종류 무관하게 동일하게 동작하게 해줘. C 계열의 언어나 맥의 스위프트와 달리 운영 체제에 종속적이거나, CPU에 연연하지 않는 게 차가운 도시인 같고, 쿨해. JVM과 바이너리 코드만 있다면 맥이든, 리눅스든, 윈도우든 어디에서든 프로그램을 만들고, 실행할 수 있지. 읽고, 검증하고, 실행하지. 아래 사진을 봐바.

 

 

나는 이클립스를 쓰지 않고, 메모장으로 자바 프로그래밍을 했었어. 이클립스같은 IDE를 사용하며 잘 모르겠지만. 자바 파일은 이렇게 구동해

 19시즌의 나는 이렇게 공부했어, powershell을 키고, javac trash.java를 한 후 바이트 코드인 trash.class를 만들었지. 클래스 마다 하나 씩 나오니, 꽤 양이 많은 코드에는 여러 개의 class 파일이 나왔어. 이러한 과정들이, 플랫폼의 독립성을 보장한다니, 놀랍지 않아?

 

JVM의 특징은 이 외에도 여러 가지가 있지. 심볼릭 레퍼런스를 사용해 클래스와 인터페이스를 심볼릭 레퍼런스를 통해 참조하고, 심볼릭 레퍼런스란 참고하는 클래스의 특정 메모리 주소를 참조 관계로 구성한 것이 아닌 참조하는 대상의 이름만을 지칭한 것을 의미해. 또한 네트워크 바이트 순서는 32bit의 RISC CPU와 64bit인 x86 CPU는 각 각 상위 바이트, 하위 바이트부터 적재를 시작해, 이같은 차이에 JVM은 빅 엔디안 즉 상위 바이트부터 적재를 하는 방식을 채택했지.

 

  잡설은 각설하고, 메인 클래스 파일을 실행시킨 다면, JVM의 클래스 로더가 반겨줘, 클래스 로더는 런타임 데이터 영억에 데이터들을 적재하고, 실행엔진이 자바 바이트 코드를 실행시키는 구조였지. 여기서 클래스 로더와 런타인 데이터 영역이 중요해, 내가 멘탈이 나갔던 문제였거든.

 

 먼저 클래스 로더부터, 클래스 로더는 총 4가지로 BootStrap ClassLoader, Extention ClassLoader, System ClassLoader, User-Defined Class Loader가있어.

 이중 첫 번째인 BootStrap ClassLoader는 네이티브 코드로 구현되어있으며, JVM이 실행될 때 가장 먼저 실행되는 클래스 로더야. 네이티브 코드(컴퓨터에 입력하면 바로 동작하는 코드)를 사용했기에, 실행 속도가 제일 빠르지. 그래서 자바 실행에 필요한 기본적인 클래스를 로딩하는 역할을 맡고 있어.

 두 번째인 Extention ClassLoader은 다양한 보안 확장 기능을 로딩하며, 별도로 클래스 패스에 지정되지 않아도 로딩해.

 세 번째는 System ClassLoader, ClassPath에 정의 되어 있거나, -cp, -classpath에 지정된 클래스들이 로딩되며, 사용자가 지정한 $CLASSPATH의 클래스들을 로드하는 역할이야.

 마지막 User-Defined Class Loader은  Jar 또는 War로 압축된 ClassPath의 Binary Code를 사용자가 직접 사용하는 클래스 로더야.

 

 런타임 데이터 영역은 자바의 메모리 영역이야. 총 6가지로 구성되어 있어. 

 

 첫 번째는 PC 레지스터, CPU 안의 PC 레지스터 처럼, JVM 수행하고 있는 명령의 주소를 갖고 있어.

 두 번째는 JVM Stack, 스레드가 시작될 때 스레드마다 하나 식 생성돼. Stack은 자료구조에서 배우듯 pop과 push 기능으로만 작동하지.

 세 번째는 Native Method Stack이야 JVM Stack과 비슷하지만 Java Native Interface을 통해 호출되는 C 계열의 코드만을 수행하기 위한 스택이지.

 네 번째, Method Area는 JVM이 시작될 때마다 생성돼. JVM이 읽어들인 클래스나 인터페이스의 정보 중 일부(필드와 메서드 정보, Static 변수, 메서드의 바이트코드 등등)를 보관하는 역할을 하고 있어, Method Area 덕분에, static이나 전역 변수 등이 Method Area로 올라가, 어느 쓰레드에서든 전역 변수 값에 접근할 수 있어.

 다섯 번째는  Runtime Constant Pool은  클래스와 인터페이스의 상수뿐만 아니라, 메서드와 필드에 대한 모든 레퍼런스까지 담고 있는 테이블이야. JVM은 어떤 메서드나 필드를 참조할 때 Runtime Constant Pool을 통해 실제 메모리상 주소를 찾아 참조해.

 마지막 Heap은 인스터스나 객체를 저장하는 가비지 컬렉션 대상이야. 단 하나의 Heap 영역이며, Object 타입은 전부 heap에 생성돼.

 

 

 

 

 

 

 

 

 

+ Recent posts