1. 하나의 명령은 하나의 프로세스에 해당합니다.
Java 프로그램을 시작하면, 즉 메인 메소드를 시작하면 프로세스가 아무리 복잡하더라도 Java 가상 머신 프로세스가 시작됩니다. 서로 다른 JVM 프로세스는 서로 영향을 미치지 않습니다. 이것이 Java 프로그램에 단 하나의 입구, 즉 가상 머신이 호출하는 메인 메소드만 있다고 말하는 이유입니다. 두 가지 주요 메소드는 두 개의 서로 다른 클래스 로더를 시작하고 실제로 서로 다른 클래스를 작동하는 두 개의 JVM 프로세스에 해당합니다. 따라서 서로 영향을 미치지 않습니다.
2. 수업 로딩.
클래스를 사용할 때 클래스가 메모리에 로드되지 않은 경우 시스템은 로드, 연결 및 초기화를 통해 클래스를 초기화합니다.
1. 클래스 로딩: 클래스의 클래스 파일을 JVM으로 읽어 들여 클래스 객체를 생성하는 것을 말합니다.
2. 클래스 연결: 클래스의 바이너리 데이터를 JRE에 병합하는 것을 말하며 이는 세 단계로 나뉩니다.
a) 확인: 로드된 클래스 파일 데이터가 올바른지 확인합니다.
b) 준비: 클래스의 정적 변수에 저장 공간을 할당하고 기본 초기화를 수행합니다.
c) 구문 분석: 클래스의 이진 데이터에 있는 기호 참조를 직접 참조로 바꿉니다.
3. 초기화: 클래스의 정적 변수 및 정적 초기화 블록을 초기화합니다.
(참고: 최종 유형의 정적 속성의 경우 컴파일 타임에 속성 값을 얻은 경우 속성을 호출해도 클래스가 초기화되지 않습니다. 이는 상수를 사용하는 것과 동일하기 때문입니다.
ClassLoader() 메서드를 사용하면 클래스만 로드되고 초기화되지는 않습니다. )
3. 클래스 로더.
클래스 로더는 .class 파일을 메모리에 로드하고 해당 java.lang.Class 객체를 생성하는 역할을 하며, 클래스가 JVM에 로드되면 다시 로드되지 않습니다.
Java에서 클래스는 정규화된 클래스 이름(즉, 패키지 이름 + 클래스 이름)으로 식별됩니다.
JVM에서 클래스는 정규화된 클래스 이름과 클래스 로더로 식별됩니다.
JVM이 실행 중이면 BootstrapClassLoader(루트 클래스 로더), ExtClassLoader(확장 클래스 로더) 및 AppClassLoader(시스템 클래스 로더)라는 세 가지 ClassLoader가 생성됩니다. UML 구조는 다음과 같습니다.
그 중 BootstrapClassLoader는 JRE의 핵심 클래스 라이브러리를 로드하는 역할을 담당합니다. ClassLoader의 하위 클래스가 아니며 C++로 작성되므로 해당 하위 클래스의 getParent() 메서드를 통해 얻을 경우 null이 발생합니다. 반환됩니다. BootstrapClassLoader는 JRE 대상 아래에 rt.jar 및 charsets.jar과 같은 Java 핵심 클래스 라이브러리를 로드하는 역할을 합니다.
그림에서 볼 수 있듯이 ExtClassLoader와 AppClassLoader는 ClassLoader의 하위 클래스이다. API에서는 볼 수 없으며 rt.jar 파일에 있습니다. 정규화된 클래스 이름은 다음과 같습니다.
sun.misc.Launcher$ExtClassLoader 및 sun.misc.Launcher$AppClassLoader.
그 중 ExtClassLoader는 JRE 확장 디렉터리 ext에 JAR 패키지를 로딩하는 역할을 담당하고, AppClassLoader는 Classpath 경로 아래에 클래스 패키지를 로딩하는 역할을 담당한다.
테스트는 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
패키지 com.stopTalking.crazy;
공개 클래스 TestClassLoader {
공개 정적 무효 메인(String[] args) {
//현재 스레드의 클래스 로더를 가져옵니다.
ClassLoader 로더 = Thread.currentThread().getContextClassLoader();
//System 클래스의 클래스 로더를 가져옵니다.
ClassLoader loader1 = System.class.getClassLoader();
//이 클래스의 클래스 로더 loader2를 가져옵니다. TestClassLoader
ClassLoader loader2 = TestClassLoader.class.getClassLoader();
//loader2의 상위 클래스를 가져옵니다.
ClassLoader loader3 = loader2.getParent();
//loader2의 상위 클래스의 상위 클래스를 가져옵니다.
ClassLoader loader4 = loader3.getParent();
System.out.println(로더);
System.out.println(loader1);
System.out.println(loader2);
System.out.println(loader3);
System.out.println(loader4);
}
}
콘솔 출력:
다음과 같이 코드 코드를 복사합니다.
//현재 스레드 클래스에서 얻은 클래스 로더는 AppClassLoader입니다.
sun.misc.Launcher$AppClassLoader@6b97fd
//시스템 클래스는 루트 로더에 의해 로드되며 Java에서는 액세스할 수 없으므로 null입니다.
null
//이 클래스의 클래스 로더는 물론 AppClassLoader이기도 합니다.
sun.misc.Launcher$AppClassLoader@6b97fd
sun.misc.Launcher$ExtClassLoader@1c78e57
null