JVM 작동원리
JVM 은 자바응용프로그램을 실행하기 위한 런타임 엔진의 역할을 함
JVM은 자바코드에 있는 MAIN 메소드를 실제 호출하는 것
JVM은 JRE의 일부
JAVA 응용 프로그램은 WORA( WRITE ONCE RUN ANYWHERE) 라고 함 이는 프로그래머가 하나의 시스템에서 JAVA 코드를 개발할수 있고 조정없이 다른 JAVA 지원 시스템에서 JAVA 코드가 실행될 수 있음을 의미 이것은 JVM 때문에 모두 가능
클래스 로더의 역할
로드, 연결, 초기화
로드 : 클래스 로더는 .CLASS 파일을 읽고 해당 데이터를 생성한 다음 메소드 영역에 저장
각 .CLASS 파일에 대해 JVM은 메소드 영역에 다음 정보를 저장함
1. 로드된 크래스 및 적접적인 부모 클래스의 정규화된 이름
2. .CLASS 파일이 CLASS 또는 INTERFACE 또는 ENUM과 관련이 있는지 여부
3. 변수와 메소드의 정보 등
.CLASS 파일을 로드한 후 JVM은 클래스 유형의 오브젝트를 작성하여 힙 메모리에 표기합니다. 이 객체는 java.lang패키지에 미리 정의된 class유형이며 이객체 참조를 얻으려면 object 클래스의 getClass() 메서드를 사용가능
연결 : 확인, 준비, 해결
확인 : .class 파일의 정확성을 보장한다. 즉, 유효한 컴파일러에 의해 파일 포맷 및 생성 여부를 확인한다 확인에 실패하면 런타임 예외 java.lang.VerifyError가 발생
준비 : JVM은 클래스 변수에 메모리를 할당하고 메모리를 기본값으로 초기화한다.
해결방법 : 이는 기호 참조를 유형에서 직접 참조로 대체하는 과정이다. 이 작업은 참조된 도면요소를 찾기 위해 방법 영역을 탐색하여 수행된다.
초기화 : 이단계에서 모든 정적변수는 코드 및 정적블록에 정의된 값으로 지정됩니다.
일반적으로 세가지 클래스 로더가 존재
부트 스트랩 클래스 로더 : 모든 jvm구현에는 부트스트랩 클래스 로더가 있어야 함 java_home/ jre /lib 디렉토리에 있는 핵심 java api 클래스를 로드 하며 이경로는 일반적인 부트스트랩 경로라함
확장 클래스 로더 : 부트 스트랩 클래스로더의 자식정도로 해석가능 java_home/jre/lib/ext(확장경로)또는 java.ext.dirs 시스템 특성으로 지정된 다른디렉토리에 있는 클래스를 로드. sun.mics.Launchers $ExtClassLoader클래스에 의해 java로 구현
시스템/응용 프로그램 클래스 로더 : 확장 클래스 로더의 자식정도로 해석가능 내부적으로 java.class.paht에 매핑된 환경 변수를 사용
// Java code to demonstrate Class Loader subsystem
public class Test
{
public static void main(String[] args)
{
// String class is loaded by bootstrap loader, and
// bootstrap loader is not Java object, hence null
System.out.println(String.class.getClassLoader());
// Test class is loaded by Application loader
System.out.println(Test.class.getClassLoader());
}
}
산출:
null
sun.misc.Launcher$AppClassLoader@73d16e93
실행 방법
계층구조 원칙에 따라 클래스를 로드 함. 시스템 클래스 로더는 확장 클래스 로더에 요청하여 부스트스랩 클래스 로더에 요청을 위임함 부트스트랩 경로에 클래스가 있으면 클래스가 로드되고 그렇지 않으면 다시 요청이 확장 클래스로더로 전달되고 없으면 다시 시스템 클래스 로더로 전달됨 최종적으로
클래스를 로드하지 ㅇ못하면 실행 시 classNotFoundException이 발생함
JVM 메모리
메소드 영역 : 메소드 영역에는 정적변수를 포함하여 클래스명, 직접적인 부모클래스 이름, 메소드 변수정보와 같은 모든 클래스 레벨 정보가 저장JVM당 1개의 영역이 있으며 이는 공유됨
힙 영역 : 모든 객체 정보가 저장됨 , JVM당 하나의 영역만 존재하며 공유됨
스택 영역 : 모든 스레드에 대해 JVM은 여기에 저장된 하나의 런타임 스택을 만듬 이 스택을 활성화 레코드/ 스택 프레임이라고 함
해당 메소드의 모든 로컬 변수는 해당 프레임에 저장됨 스레드가 종료된 후에는 런타임 스택이 JVM에 의해 삭제됨 공유되지 않음
PC 레지스터 : 스레드의 현재 실행 명영의 주소를 저장함 각 스레드는 별도의 PC 레지스터를 보유함
원시 메소드 스택 : 모든 스레드으ㅔ 대해 별도의 원시 스택이 작성됨 네이티브 메소드 정보를 저장함
실행엔진 (EXCUTION ENGINE)
실행 엔진은 .CLASS(바이트 코드)를 실행 함 한줄씩 바이트코드를 읽고 다양한 메모리 영역에 있는 데이터와 정보를 사용하고 지침을 실행
실행엔진의 분류
인터 프리터 : 바이트 코드를 한줄씩 해설한 다음 실행 ,
JIT(JUST - IN TIME COMPILEER) 인터프리터의 효율성을 높이는데 사용 , 전체 바이트 코드를 컴파일하여 원시 코드로 변경하므로 인터프리터가 반복적인 메소드 호출을 볼때마다 JIT가 해당부분에 대한 직접 원시 코드를 제공하므로 효율적이다.
가비지 콜렉터 : 참조ㅈ되지 않은 객체를 파괴한다. ?