JVM과 자바 컴파일
JVM(Java Virtual Machine)
-프로그램을 실행하는 자바 플랫폼의 구성요소이다.
-JAVA 바이트 코드를 실행시키기 위한 가상의 기계.
-OS에 의존적이며 컴파일된 바이너리 코드는 어떤 JVM에서도 동작시킬 수 있다.
-자바 바이트 코드가 실행될 수 있는 런타임 환경을 제공하는 사양.
*바이트코드?
:자바 가상머신이 이해할 수 있는 언어로 변환된 자바 소스 코드.
.java -> .class 파일로 컴파일시 .class 파일내부에 jvm이 읽을 수 있는 바이트코드가 있다.
JVM 구성
JVM은 크게 4가지로 나눌 수 있다.
- Class Loader
- Execution Engine
Execution Engine은 2가지 방법으로 작동한다. 1.인터프리터(Interpreter) :명령어를 하나 하나 실행하는 방식 2.JIT(Just-In-Time) 컴파일러 :성능향상을 위해 반복되는 코드 발견시 JIT컴파일러를 통해 네이티브 코드로 변경해서 Execution Engine이 네이티브로 컴파일된 코드를 실행시키는 방식. :실행 시점에 인터프리터 방식으로 기계어 코드를 생성하면서 그 코드를 캐싱한다. 그리고 같은 함수가 여러번 동작할때 매번 기계어 코드를 생성하는 것을 방지한다. 변경된 부분만 컴파일 하기 때문에 수행속도가 인터프리터 방식에 비해 빠르
- :클래스로더에 의해 적재된 바이트코드들을 기계어로 변경해 명령어 단위로 실행하는 역할을 한다.
- Execution Engine
- : 컴파일시 생성된 바이트 코드들을 엮어서 Runtime Data Area로 적재하는 역할을 한다.
```jsx
로딩,링크,초기화 단계를 거침.
1.로딩:클래스를 읽어오는 과정.(.class 파일을 읽어서 바이트 코드를 메서드 영역에 저장.)
2.링크:레퍼런스를 연결하는 과정.
3.초기화:static값들 초기화 및 변수에 할당.
```
- Runtime Data Area:JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역.
메모리 영역은 총 5가지로 나누어 진다. 1.Method Area :class의 멤버 변수의 정보와 메소드의 정보가 저장되는 영역. 상수와 static 변수, final class 변수 등이 생성되는 영역이다. 모든 스레드에서 공유를 한다. 2.Heap Area :new 키워드로 생성된 모든 객체와 배열이 생성되는 영역. Garbage Collector가 참조되지 않은 메모리를 확인하고 제거하는 영역이다. 모든 스레드에서 공유를 한다. 3.Stack Area :지역 변수,파라미터, 리턴 value 등이 생성되는 영역이다. 만일 Member m = new Member() 라는 코드가 실행된다면 m의 인스턴스들은 힙영역에 저장이되고 스택영역에 m값에 Member의 주소값이 저장된다. 스레드마다 한개만 존재. *Stack Frame -스택 프레임은 메서드가 호출될 때마다 새로 스택에 push되고 메서드가 끝나면 pop되어 사라진다. -스택 프레임은 Local variables array, Operabd StacK, Frame Data를 갖는다. -Frame Data는 Constant Pool, 이전 스택 프레임에 대한 정보, 현재 메서드가 속한 클래스/객체에 대한 참조 정보를 갖는다 4.PC Register :Thread가 생성될 때 마다 생성되는 영역으로 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하는 영역이다. 모든 스레드에 존재 5.Native method Stack :자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역이다. 모든 스레드에 존재
Method Area와 Heap Area 모든 스레드가 공유.
- 가비지 컬렉터(Garbage collector)
- :Heap 영역에 생성된 객체들 중 참조되지 않은 객체들을 탐색 후 제거하는 역할을 한다.
JRE(Java Runtime Environment)
JVM이 자바 프로그램을 동작시킬 때 필요한 라이브러리 파일들과 기타 파일들을 가지고 있다.
JRE = JVM + Java 애플리케이션을 실행하기 위한 라이브러리.
JDK(Java Development Kit)
-컴파일러와 클래스 라이브러리를 포함하는 자바 플랫폼 사양서의 구현.
-자바 기반 애플리케이션 개발을 위해 다운로드하는 소프트웨어 패키지
JVM = JRE + Java 애플리케이션 개발툴
자바 컴파일러
-.java 파일을 받아서 실행 가능한 .class 파일로 만드는 기능이 있는 소프트웨어.
-모든 JDK는 자바 컴파일러를 포함한다.
자바 플랫폼 종류
1.Java SE
-대중적으로 사용하는 자바 플랫폼이다.
-java.lang.,java.util.,java.awt.,등
-가상 머신, 개발도구, 배포기술, 부가 클래스라이브러리, 툴킷 등을 제공한다.
2.Java EE
-Java SE를 기반으로 웹프로그래밍에 필요한 기능들을 다수 추가하여 만들어졌다.
-HTTP 요청 처리를 지원하는 자바 Serverlet 사양을 포함하고 있다.
3.Java Me
-Java SE를 기반으로 모바일 폰같은 보다 작은 가상머신에서 동작시킬 수 있는 기능과 API 제공
4.Java FX
-경량 사용자 api를 사용하여 리치 인터넷 어플리케이션을 만들때 사용.
*리치 인터넷 어플리케이션
:웹 어플리케이션의 장점을 유지하면서 기존 웹 브라우저 인터페이스의 단점(늦은 응답속도, 데스크톱보다 떨어지는 조작성) 등을 개선하기 위한 기술.
:EX)ajax,HTML5
자바 컴파일 및 실행 방법
Compile
고급언어로 작성된 소스코드를 컴퓨터가 이해할 수 있도록 기계어로 변환하는 과정.
Java에서는 .java파일을 .class 파일로 변환하는 과정을 의미한다.
실행 방법
대부분 프로그래머들은 IDE를 사용해서 개발을 하기 때문에 직접 컴파일 하는 것은 드물다.
직접 java언어를 컴파일 하기위해서는 java compiler가 필요하다.
java compiler는 jdk를 설치하면 bin 폴더 안에 javac라는 이름으로 설치가 되어져 있다.
hello.java를 만들고 이 과정을 javac를 통해 컴파일 해주겠다.
자바의 경우 파일명과 클래스 명이 같아야 하니 이 점을 유의하면서 소스코드를 작성해야 한다.
javac를 통해 .java파일이 .class파일로 바뀌는 것을 볼 수 있다. java를 통해 실행을 하면 우리가 짠대로 Hello를 출력한다.
이제 hello클래스를 패키지 형태로 바꾸어 보겠다. 패키지명은 보통 도메인의 역순으로 구성되니 위와 같은 규칙으로 해볼려고 한다. 주소명을 간단하게 choi.com으로 구성하여 진행하겠다.
왼쪽의 폴더 경로에 맞추어서 텍스트 파일에 package com.choi;를 추가해준다.
출력이 잘되는 것을 볼 수 있다. 참고로 위와 같이 package를 올바르게 설정하지 않으면 기본 클래스[클래스경로]를 찾거나 로드할 수 없다고 뜰 수도 있으니 주의하자.
javac 옵션 종류
1.classpath(cp) : 컴파일 시 필요로 하는 참조할 클래스 파일의 파일 경로를 지정.
javac -classpath [참조파일 경로][소스파일.java]
javac -cp [참조파일 경로][소스파일.java]
2.d:클래스 파일을 생성할 루트 디렉토리 설정
javac -d [루트디렉토리][소스파일.java]
3.encoding: 소스파일에 사용된 문자열 설정
javac -encoding [인코딩셋] [소스파일.java]
4.g:디버깅 정보
javac -g:none : 디버깅 정보를 생성하지 않음
javac -g:line(라인정보), var(지역변수), source(소스 파일 정보)
5.nowarn: 경고 메세지 관련 옵션. 이 옵션을 사용할 경우 경고 메세지를 생성하지 않음.
6.sourcepath: 소스파일의 위치를 지정.
리플렉션이란
구체적인 클래스 타입을 알지 못해도, 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API
리플렉션은 일반적으로 개발자보다는 프레임워크에서 많이 사용되어 진다.
프레임워크와 라이브러리는 우리가 만들어둔 코드가 어떠한 클래스고 내부구조를 알지 못한다.
이럴 때 동적으로 해결하기 위해 만들어진게 리플렉션이다.
어떻게 하여 리플렉션이라는 것이 가능한 것일까?
자바 클래스파일은 바이트 코드로 컴파일되어 Static 영역에 위치하게 된다. 그렇기 때문에 Static영역내부에 클래스와 관련된 정보를 얻어올 수 있다.
주로 스프링에서는 DI에서 리플렉션을 많이 사용하고 있다.