#오류에 대해 지적해 주시면 수정하겠습니다.
JDK
JDK = JRE + 개발툴( ex. apt, appletviewer, javac, javap, jar, jdb )
개발툴 중 대표적으로 javac를 보자면 Java코드를 컴파일 하는 친구이다. 아래 그림처럼 Java코드를 byte코드로 컴파일한다.
•apt : 어노테이션 툴
•appletviewer : 웹브라우저 없이 자바 애플릿을 실행하고 디버깅하기 위한 툴
•javac : 자바 컴파일러. 자바 소스파일을 바이트코드로 변환
•java : javac가 만든 클래스 파일을 해석 및 실행
•jar : 서로 관련있는 클래스 라이브러리들과 리소스를 하나의 파일로 묶어주는 툴
•jdb : 자바 디버깅 툴
JDK의 종류
- Java SE(Standard Edition)
Java가 어떠한 문법적인 구성을 가졌는지와 같은 것들을 나타내는 명세표
네트워킹,보안,그래픽 사용자 인터페이스 개발,XML파싱,데이터베이스 등을 지원 - Java EE(Enterprise Edition)
Java SE + 서버에서 동작하는 기능
추가적으로 웹프로그래밍에 필요한 JSP, Servlet, JDBC 등의 기능을 제공 - Java ME(Micro Edition)
Java SE + 휴대전화,PDA에서 java 프로그래밍 지원
JRE
JRE = JVM + Java Class Library
Java Class Library는 런타임시 클래스 로딩이 발생하는데 그때 참조하는 class들이 모여있는 도서관이다.
Class Loader의 위치에 대한 고찰은 Class Loading에 대해서 다룰때 더 자세히 언급하겠다. 일단은 JVM에 포함 시켰다.
JVM
다른 언어는 OS의 종류에 따라, CPU아키텍처에 따라 동작안한다. 그니까 컴파일한 환경이랑 그 프로그램을 실제 동작시킬 환경이랑 다르면 동작이 안할 수도 있다는 뜻이다. 따라서 컴파일 된 코드를 어디서나 실행 될 수 있도록 하기위해 탄생한게 JVM이다.
JVM의 구성요소
JVM은 크게 Class Loader, Execution Engine, Runtime Data Areas로 나누어져 있다.
•Class Loader Subsystem – 로드, 링크 및 초기화 담당, 동적 클래스 로드라고도 함
(클래스로더 편에서 자세히 다룰예정)
•Runtime Data Areas – method areas, PC registers, stack areas, threads.
(JVM의 메모리 구조편에서 자세히 다룰 예정)
•Execution Engine – interpreter, compiler , garbage collection area.
(JVM의 메모리 구조편과 GC편에서 자세히 다룰 예정)
JVM의 특징
1. 스택 기반의 가상머신
2. 심볼릭 레퍼런스
3. 가비지 컬렉션
4. 기본 자료형을 명확하게 정의하여 플랫폼 독립성 보장
5. 네트워크 바이트 오더(network byte order)
이들 중 가비지 컬렉션은 GC편에서 자세히 보도록 하고, 1,2,5번을 중점으로 보겠다.
스택 기반의 가상머신?
일단 스택 기반과 대조되는 레지스터 기반 가상머신을 보겠다.
5 + 30 + 40 을 계산한다고 하면, CPU의 덧셈 연산은 2개의 피연산자를 다루므로 5 + 30 를 계산한 결과를 40 과 더해야만 한다. 레지스터 기반의 VM은 피연산자를 레지스터에서 가져와서 계산하고, 결과를 다시 레지스터에 저장한다.
즉, 레지스터 기반의 VM은 피연산자를 레지스터에서 가져와서 계산한 뒤 다시 레지스터에 저장한다. 레지스터 기반의 VM의 장단점은 다음과 같다.
명령어의 수가 적고 스택을 사용하지 않아 스택에 대한 오버헤드가 없으나 명령어의 크기가 커지고, 명령어에 오퍼란드를 명시해야 하므로 명령어가 길어진다.
이번에는 스택 기반 가상머신을 보겠다.
13 + 20 + 7 을 계산한다고 하자. CPU의 덧셈 연산은 2개의 피연산자를 다루므로 20 + 7 를 계산한 결과를 13 과 더해야만 한다. 스택 기반의 VM은 이 결과를 바로 스택에 저장한다. 위 그림을 보면, 20과 7을 더하기 위해서 두 피연산자를 스택에서 꺼낸다. 꺼낸 결과를 가지고 계산한 뒤에 다시 결과를 스택에 넣는 것을 알 수 있다.
즉, 스택 기반의 VM은 피연산자를 저장하고 가져올 때 스택을 활용한다. 스택 기반의 VM의 장단점은 아래와 같다.
이러한 스택 기반의 VM은 명령어의 수가 많아지고 오버헤드에 대한 위험성이 존재한다.
하지만 그럼에도 JVM이 스택기반을 쓰는 이유는 JVM의 모토가 WORA이기 때문이 아닐까.
레지스터 기반의 가상머신은 CPU내의 레지스터에 저장하기 때문에 하드웨어 의존적이 되기 쉽다. 예를들면 레지스터 개수나, 레지스터의 사이즈 같은 것들이 있다.
심볼릭 레퍼런스?
아까 말한것처럼 .java를 컴파일해서 만들어진 파일이 .class파일이다.
컴파일 된 바이트코드를 javap를 사용해 역 어셈블리화해보면 아래와 같다. 이러한 결과물을 자바 어셈블리라고 부른다.
위에서 다섯번째 줄에있는 5: invokevirtual #23; 를 보자.
Invokevirtual은 메서드를 호출하는 대표적인 명령어다. 그밖에도 아래와 같은 것들이 있다.
•invokeinterface: 인터페이스 메서드 호출
•invokespecial: 생성자, private 메서드, 슈퍼 클래스의 메서드 호출
•invokestatic: static 메서드 호출
•invokevirtual: 인스턴스 메서드 호출
자바 바이트코드의 명령어는 OpCode와 피연산자(Operand)로 분리할 수 있으며, invokevirtual과 같은 OpCode는 2바이트의 피연산자를 필요로 한다. 당연히 무언가를 호출하는 명령어니까 피연산자가 필요하다.
그니까 5: invokevirtual #23; 를 해석해보면, 코드앞에 숫자 (지금같은경우는 5)는 바이트번호이고 뒤에 #23은 피연산자이다. 그니까 23번에 해당하는 인스턴스 메서드를 호출하라는 뜻인 것이다.
JVM을 거치면서 .class파일은 실행가능한 형태로 바뀌게 되는데 이때 JVM에서 실행가능한 형태로 바뀌는 과정을 Linking이라 부른다. 이처럼 .class파일은 그때그때 Link를 할 수 있도록 Symbolic Reference만을 가지고 있다.
이러한 Linking은 필요할때마다 동적으로 이루어지기 때문에 Dynamic Linking이라 부르게 되었다.
이 다이나믹 링킹 기술 덕분에 class의 크기를 작게 유지할 수 있었고 Network를 통해 배포하는데 유리하다.
Class파일의 4가지 특징
1. Compact한 형태
2. Bytecode로의 변경
3. Platform 독립적
4. 네트워크 바이트 오더(network byte order)
네트워크 바이트 오더?
일단 네트워크 바이트 오더를 말하기전에 엔디안(Endian)이라는 말을 알아야한다.
엔디안이라는 말은 걸리버 여행기에서 소인국 릴리퍼트 이야기에서 달걀을 깰때 뭉뚝한 끝을 먼저 깨는 사람들, 뾰족한 끝을 먼저 깨는 사람들 사이에 싸운거에서 따온거라고 한다.
마치 한국의 부먹 찍먹같은거 인가보다. 마찬가지로 빅 엔디안과 리틀 엔디안 중 무엇을 쓰는지에 대해 논란이 있는편이라고 한다.
일단 컴퓨터는 1Byte단위로 읽기 때문에 bit를 읽는 순서는 변하지 않는다.
하지만 Byte를 읽는 순서는 CPU마다 차이가 있다고 한다. 그러므로 바이트 오더는 바이트를 읽는 순서를 의미한다.
바이트 오더는 빅 에디안 방식과 리틀 에디안 방식으로 나뉘는데 각각
빅 에디안 방식은 상위비트 -> 하위비트 순으로,
리틀 에디안 방식은 하위비트 -> 상위비트 순으로, 읽는다.
자바 클래스 파일은 네트워크 전송 시에 사용하는 바이트 오더인 네트워크 바이트 오더를 사용한다.
네트워크 바이트 오더는 빅 엔디안이다. 이러한 사실은 JAVA가 설계될때부터 Network를 고려했음을 알게 해준다.
https://d2.naver.com/helloworld/1230
https://www.ibm.com/cloud/blog/jvm-vs-jre-vs-jdk
책 – JAVA PERFORMANCE FUNDAMENTAL, 김한도, 엑셈(2009)
https://korecmblog.com/jvm-seutaeg-giban-vmgwa-rejiseuteo-giban-vm/
'Programming Language > JAVA' 카테고리의 다른 글
[JAVA스터디]Lambda (0) | 2021.09.22 |
---|---|
[JAVA스터디]다형성(Polymorphism) (0) | 2021.08.15 |
[JAVA스터디]자바 입출력(2)-직렬화/역직렬화 (0) | 2021.08.11 |
[JAVA스터디]자바 입출력(1)-System,Stream,표준입출력,객체입출력 (0) | 2021.08.10 |