-
[SpringBoot - Step 1] Java, JVM 구동원리Java/SpringBoot 2.0 2019. 1. 12. 22:30
개인블로그를.. 잠시 접어두고 티스토리 서비스를 익히고자 블로그를 시작한지 벌써 6개월이 지났는데 이핑계 저핑계를 만들며 많이 써보지 못했다. ㅠㅠ
이번에 스프링부트 스터디를 하게 되었고 이내용들을 쭉쭉 정리할 생각이다.
내가 얼마나 기억하고 있을지..끝까지 잘 마무리할 수 있을지 .....걱정이다 ㅋ
자바의 구동원리
1. 컴파일러를 통해 JAVA 코드 검증과 JVM이 이해할 수 있는 바이트코드(.CLASS)로 만듬
2. .CLASS를 찾아 JVM으로 가져옴
3. 바이트코드 검증
4. 인터프린트(재해석)
5. 바이트코드를 바이너리코드로 변경(바이너리 코드는 JVM의 클래스 영역에 저장)
6. 런타임 과정에서는 클래스들의 static 변수를 자동 초기화
7. static 블록 수행
8. 인스턴스 블록 수행
9. 생성자 호출
10. main 함수 호출
JVM
1. JVM은 OS로부터 메모리를 할당받는다.2. 자바컴파일러(javac)가 자바 소스코드(.java)을 바이트코드(.class)로 변환한다.3. 클래스로더를 통해 .class파일들을 JVM으로 로딩한다.4. 로딩된 .class파일들은 Execution engine을 통해 해석된다.5. 해석된 바이트코드는 Runtime Data Areas에 배치되어 실질적인 수행이 이루어지게 된다.6. 때에 따라 Thread Synchronization과 GC같은 관리 작업을 수행한다.클래스 로더
- 컴파일 단계가 아닌 런타임시에 컴파일된 자바 바이트코드를 Excution Engine이 실행을 하면서 Runtime Data Area에 로드한다.
- 부트스트랩 클래스로더 : 자바 API 로드
- 익스텐션 클래스 로드 : 기본 자바 API을 제외한 확장 API을 로드 한다.
- 시스템 클래스 로드 : CLASSPATH에 정의된 클래스들을 로드 한다.
- 사용자 정의 클래스 : 개발자가 직접 코드상에 생성한 클래스들을 로드 한다.
- 이처럼 단계별 절차를 걸쳐 클래스들을 로드 한 후 보관하기 위하여 디렉토리 구조를 갖는다.
Execution Engine(실행엔진)
- .class파일을 실행시키는 역할이다.
- 클래스로더가 JVM 런타임에 바이트코드를 배치하고 이것을 실행하는 것이 실행엔진이다.
- 자바 바이트코드는 기계가 바로 수행할 수 있는 언어가 아니라 인간이 비교적 보기 편하게 기술한 것 그래서 바이트코드로 실제로 JVM내부에서 기계가 실행 할 수 있도록 변환한다. 그 방법이 아래 두 가지가 있다.
1. Interpreter(인터프리터)
- 실행 엔진은 자바 바이트 코드를 명령어 단위로 읽어 실행.
- 느리다
2. JIT (Just – In – Time)
- 언터프리터의 단점을 보완하기 위해 JIT 컴파일러 도입
- 인터프리터로 실행하다 적절한 시점에 바이트코드 전체를 컴파일 하여 네이티브 크드로 변경 그 이후에는 인터프린터 하지 않고 네이티브 코드로 직접 실행.
- JIT 컴파일러를 사용하는 JVM은 내부적으로 해당 메서드가 얼마나 자주 수행되는지 체크하고 일정 정도를 넘을때에만 컴파일을 수행한다.
Runtime Data Area
PC 레지스터
쓰레드별로 하나씩 생성
쓰레드가 어떤 부분을 어떤 명령으로 실행 해야 할지에 대한 기록
현재 수행중인 JVM 명령의 주소를 갖는다.
연산의 결과를 잠시 CPU 어딘가에 저장을 해야되며 그장소가 CPU의 Register이다.
JVM 스택
프로그램 실행과정중 임시로 할당 되었다가 메소드를 빠져나가면 바로 소멸되는 특성의 데이터를 저장하는곳.
메소드 호출시마다 각각의 스택프레임(그메서드만을 위한공간) 이 생성된다.
메소드 호출이 끝나면 스택프레임별로 삭제된다.
변수, 임시데이터, 스레드나, 메소드 정보, 메소드 안에서 사용되는 값들을 저장한다.
호출된 메소드의 매개변수, 지역변수, 리턴값 및 연산시 일어나는 값들을 임시로 저장한다.
Native method stack
자바 외의 언어로 작성된 네이티브 코드를 위한 스택이다 즉 Java Native Interface (JNI)을 통해 호출하는 C, C++등의 코드를 수행하기 위한 스택이다.
Method Area = Class area = Static area
클래스 정보를 처음 메모리 공간에 올릴때 초기화되는 대상을 저장하기 위한 공간
올라가게되는 메소드의 코드는 프로그램의 흐름을 구성하는 바이트 코드 이다.
Runtime Constant Pool도 존재 : 상수 자료형을 저장하여 참조하고 중복을 막는 역할 수행
상수값만 저장 하는 것이 아니라 메서드와 필드에 대한 모든 레퍼런스 까지 담고 있는 테이블을 갖고 있다. JVM 런타임 상수풀을 통해 해당 메서드나 필드의 실제 메모리 주소 값을 찾아서 사용한다.
올라오는 내용
Field Information : 멤버 변수의 이름, 데이터 타입, 접근 제어자에 대한 정보
Method Information : 메소드 이름, 리턴타입, 매개변수, 접근제어자에 대한 정보
Type Information : class인지 interface인지의 여부 저장
Heap (힙 영역)
객체를 저장하는 공간New 연산자로 생성된 객체와 배열을 저장한다.Method Area (Class Area)에 올라온 객체만 올라올 수 있다.Heap은 다시 Edan, Survivor 0, Survivor 1, old, Permanent로 분리된다.
Permanent Generation
생성된 객체들의 정보의 주소값이 저장되는 공간.
클래스 로더에 의해 로드되는 Class, Method등에 대한 메타 정보가 저장
JVM에 의해 사용된다. Reflection을 사용할 때 동적으로 클래스를 로딩되는 경우 사용
Reflection : 객체를 통해 클래스의 정보를 분석하는 프로그램, 스프링 Container의 BeanFactory는 어플리케이션이 설정한 후 객체가 호출될 당시의 객체의 인스턴스를 생성하는데 그때 Reflection이 필요.
New/Young 영역
Edan : 객체들이 최초로 생성되는 공간
Survivor 0 / 1 : Edan에서 참조되는 객체들이 저장되는 공간
Old 영역
New area에서 일정 시간 참조되고 있는 살아남은 객체들이 저장되는 공간
Edan영역에 객체가 가득차게 되면 첫번째 GC가 발생
Edan영역에 있는 값들은 Survivor 1영역에 복사하고 이영역을 제외한 나머지 영역의 객체를 삭제한다.
인스턴스는 소멸 방법과 소멸 시점이 지역변수와는 다르기에 힙이라는 별도의 영역에 할당된다.
자바 가상머신은 매우 합리적으로 인스턴스를 소멸시킨다. 더 이상 인스턴드스의 존재 이유가 없을때 소멸한다.
'Java > SpringBoot 2.0' 카테고리의 다른 글
[SpringBoot - Step 4] 스프링 프레임워크 & DispatcherServlet (0) 2019.01.13 [SpringBoot - Step 3] Servlet/서블렛 (0) 2019.01.13 [SpringBoot - Step 2] 클래스로더 & Web appliation (0) 2019.01.12