자바의 대해 공부하면서 아직까지도
JVM, JRE, JDK를
자세히 모르고 있다.
자바를 제대로 사용하기 위해서라도 이세가지 공부는 중요하다고 생각된다.
간단하게라도 글로 정리해보려고 한다.
1. JVM
- JVM (Java Virtual Machine)자바 가상머신 이다.
- 자바를 실행하기 위한 가상 기계라고 직역할수있다.
- 자바 바이트 코드를 ,인터프리터와 JIT컴파일러를 이용하여 OS에 특화된 코드로 변환하여 실행한다.
- 이때 OS로부터 메모리를 할당해주는 역할도 한다.
- 각각의 플랫폼 마다 JVM이다르다.
- 이특증 덕분에 Java 가 OS에 구애받지 않고 재사용을 가능하게 해주는 장점이다.
- 메모리 관리도 탁월하다.
- Garbage Collection(GC, 가비지 컬렉션)이 JVM에 속한다.
- 더이상 참조되지 않는 객체를 모아서 정리해준다.
- Java는 플랫폼에 종속적이지 않지만 JVM은 플랫폼에 종속적이다.
- 이렇게 Java는 컴파일된 바이트코드로 어떤 JVM에서도 동작시킬 수 있기 때문에 플랫폼에 의존적이지 않다.
- 하지만 반대로 자바 가상 머신(JVM)은 플랫폼에 의존적이다 즉 리눅스의 JVM과 윈도우의 JVM은 서로 다르다.
2. JRE
- 자바 실행환경(Java Runtime Environment)이다.
- JVM + 라이브러리
- JVM이 자바 프로그램을 동작시킬 때 필요한 ‘핵심 라이브러리 및 자바 런타임 환경에서
- 사용하는 프로퍼티 세팅이나 리소스 파일’을 가지고 있다.
- 컴파일 된 자바 프로그램을 실행하는 데에 필요한 패키지이다.
3.JDK
- 자바 개발도구(Java Development Kit)’이다.
- JRE + 개발에 필요할 툴
- 사실 개발자들은 개발을 해야하기 때문에 JRE만 다운받는 일은 거의 없다.
- 그래서 오라클은 자바 11부터는 JDK만 제공하며 JRE를 따로 제공하지 않는다
4. JVM의 구조
- JVM의 5가지 영역
- 클래스 로더 시스템
- .class에서 바이트코드를 일고 메모리에 저장한다.
- 메모리
- 클래스 로더를 통해 로드된 클래스들과 실행 과정의 정보들을 저장한다.
- 실행 엔진
- 인터프리터와 JIT 컴파일러’를 통해 바이트 코드를 읽고 실행한다.
- Garbage Collection(GC, 가비지 컬렉션)’을 통해 메모리를 정리한다.
- 네이티브 메소드 인터페이스(JNI)
- 자바 애플리케이션에서 C, C++, 어셈블리로 작성된 함수를 사용할 수 있는 방법을 제공한다.
- Native 키워드를 사용하여 네이티브 메소드를 호출할 수 있다.
- 네이티브 메소드 라이브러리
- C, C++로 작성 된 라이브러리이다.
- 클래스 로더 시스템
- 이 중, ‘메모리 영역’에 대해 조금 더 구체적으로 들어가보자.
5. JVM 메모리의 구조
- JVM 메모리의 5가지 영역
- 스택(stack)
- 각 쓰레드마다 하나의 런타임 스택을 만든다.
- 메소드 호출을 ‘스택 프레임’이라 부르는 블럭으로 쌓고, 쓰레드를 종료하면 런타임 스택도 사라진다.
- 스택 프레임마다 각 메소드의 지역변수, 인자값, 리턴값이 저장된다.
- PC(Program Counter) 레지스터
- 각 쓰레드마다 가장 최근에 실행되고 있는 메소드를 가리키는 역할을 맡는다.
- 네이티브 메소드 스택
- 네이티브 방식의 메소드란 Java가 아닌 다른 언어로 작성된 코드를 의미한다.
- 일반적으로 JVM은 네이티브 방식을 지원한다.
- 쓰레드에서 네이티브 방식의 메소드가 실행되는 경우, Native Method Stack에 쌓이게 된다.
- 스택(stack)
- 일반적인 메소드를 실행하는 경우 동작 과정
- JVM 스택에 쌓인다.
- 해당 메소드 내부에 네이티브 방식을 사용하는 메소드 ( ex) c언어로 작성된 메소드)가 있으면, 해당 메소드는 네이티브 스택에 쌓인다.
- 힙(heap)
- 모든 쓰레드가 공유하는 영역이다.
- 자바 프로그램에서 사용되는 모든 인스턴스 변수(객체)들이 저장된다.
- 자바에서는 new를 사용하여 객체를 생성하면 힙 영역에 저장된다.
- 메소드(method)
- 모든 쓰레드가 공유하는 영역이다.
- 클래스 수준의 정보들 (클래스 이름, 부모 클래스 이름, 생성자, 메소드, 변수 등) 을 저장한다.
- static, 상수 등 구분없이 모든 클래스들의 정보가 저장된다.
6. 리플렉션을 배우기 전에 명확히 짚고 넘어가야 할 부분 Permalink
- 클래스의 완전한 이름은 ‘패키지 이름, 클래스 이름, 클래스 로더 이름’으로 구성되어 있다.
- 즉, 패키지 이름과 클래스 이름까지 같다고 해도, 각 클래스를 로딩한 클래스 로더가 ‘다른 클래스 로더’라면 충돌이 일어나지 않는다.
- 반대로 같은 객체가 아니기 때문에, 같은 객체로 취급하고 작업을 진행하면 원하지 않는 방향으로 동작된다.
- 다음 글인 리플렉션 정리 글에서 ByteBuddy의 예제를 보면 알 수 있다.
- 코드상에서 ‘new 연산자’ 혹은 ‘클래스.class’ 등등을 통해 클래스가 한 번이라도 로드되었을 때, 힙 영역에 Class‘ 형식의 객체로 저장이 된다.
- 모든 리플렉션의 시작은 ‘Class‘ 부터 시작한다.
- 참고로 클래스 로딩 후 만들어지는 ‘Class’ 객체와 new 연산자를 통해 생성된 ‘Book’ 객체는 다른 객체임을 인지하자.
- 인스턴스 변수.getClass()’ 혹은 ‘클래스 이름.class’ 를 통해 힙 영역에 저장되어있는 ‘Class‘ 에 접근할 수 있다.
'개발 > Java' 카테고리의 다른 글
Java) 컬렉션 프레임웍 이란? (0) | 2024.04.16 |
---|---|
JSoup 을이용하여 Java웹 크롤링 (0) | 2024.01.09 |