자바 클 라 스 파일 컴 파일 로 딩 과정 을 인 스 턴 스 로 분석 합 니 다.
우선 자바 가 어떻게 인 코딩 에서 실행 되 는 지 볼 까요?우 리 는 x.java 파일 이 javac 명령 을 실행 하면 x.class 파일 이 될 수 있 습 니 다.자바 명령 을 호출 할 때 class 파일 은 메모리 에 불 러 옵 니 다.이 과정 을 classloader 라 고 합 니 다.일반적으로 우리 가 코드 를 쓸 때 자바 라 이브 러 리 를 사용 하기 때문에 불 러 올 때 자바 라 이브 러 리 와 관련 된 클래스 도 메모리 에 불 러 옵 니 다.마 운 트 가 완료 되면 바이트 디 스 플레이 와 JIT 인 스 턴 트 컴 파일 러 를 호출 하여 설명 과 컴 파일 을 진행 합 니 다.컴 파일 이 끝 난 후 실행 엔진 에서 시작 합 니 다.실행 엔진 아래 에 대응 하 는 것 은 운영 체제 하드웨어 입 니 다.다음 그림 은 대체적인 절차 이다.
자바 는 크로스 플랫폼 의 언어 라 고 하 는데 JVM 은 크로스 언어 플랫폼 이 라 고 할 수 있다.
질문 이 있 습 니 다.자바 는 실행 을 설명 하 는 것 입 니까?컴 파일 실행 을 설명 하 는 것 입 니까?답:해석 과 컴 파일 은 혼합 할 수 있 습 니 다.특히 자주 사용 하 는 코드 나 코드 가 사용 하 는 횟수 가 매우 많 을 때 하나의 실시 간 컴 파일 을 로 컬 컴 파일 로 만 들 면 어느 정도 효율 을 높 일 수 있 습 니 다.
자바 가상 머 신 은 어떻게 이렇게 많은 언어 를 위 에서 실행 할 수 있 습 니까?관건 은 class 파일 입 니 다.모든 언어 가 class 파일 로 컴 파일 되 고 class 파일 의 규범 에 부합 하면 자바 가상 머 신 에서 실행 할 수 있 습 니 다.
2.class 파일 의 로드 과정 을 자세히 설명 합 니 다.
다음은 클 라 스 파일 이 하 드 디스크 에서 메모리 까지 어떻게 실행 되 는 지 설명 한다.
클래스 로드 는 주로 세 가지 과정 이 있 습 니 다.loading,linking,initializing;그 중에서 linking 은 세 가지 절차 로 나 뉘 는데 그것 이 바로 verification,preparation,resolution 이다.
1、우선 Loading 은 무슨 뜻 인가요?클래스 의 가격 을 메모리 에 로드 하 는 것 입 니 다.
2.다음 링크 는 세 단계 로 나 뉜 다.
다음은 클래스 로 딩 과정의 간략화 그림 입 니 다.
클래스 로 더 의 로드 과정 은 서로 다른 차원 으로 불 러 옵 니 다.서로 다른 클래스 로 더 는 서로 다른 class 파일 을 불 러 옵 니 다.Bootstrap>Extension>application>Custom(사용자 정의 클래스 로 더)
1.첫 번 째 클래스 로 더 의 단 계 는 Bootstrap 을 시작 클래스 로 더 라 고 부 르 며 자바 클래스 로 더 계층 의 맨 위 클래스 로 더 입 니 다.JDK 의 핵심 라 이브 러 리 를 불 러 옵 니 다.
2.두 번 째 클래스 로 더 의 단 계 는 Extension 은 확장 클래스 를 불 러 오 는 데 사 용 됩 니 다.주로 자바 의 확장 라 이브 러 리 를 불 러 옵 니 다.기본 으로 JAVA 를 불 러 옵 니 다.HOME/jre/lib/ext/디 렉 터 리 에 있 는 모든 jar 패키지 입 니 다.
3.세 번 째 클래스 로 더 의 단 계 는 응용 프로그램 을 시스템 클래스 로 더 라 고도 부 릅 니 다.JVM 이 시 작 될 때 명령 자바 에 있 는 classpath 나 java.class.path 시스템 속성 이나 CLASSPATH 운영 체제 속성 이 지정 한 JAR 클래스 패키지 와 클래스 경 로 를 불 러 옵 니 다.
4.세 번 째 클래스 로 더 의 단 계 는 사용자 정의 ClassLoader(사용자 정의 로 더)입 니 다.
package com.example.demo.classloader;
public class ClassLoaderScope {
public static void main(String[] args) {
System.out.println("-------------------Bootstrap -------------------");
String property = System.getProperty("sun.boot.class.path");
String s = property.replaceAll(";", System.lineSeparator());
System.out.println(s);
System.out.println("-------------------Ext -------------------");
String property1 = System.getProperty("java.ext.dirs");
String s1 = property1.replaceAll(";", System.lineSeparator());
System.out.println(s1);
System.out.println("-------------------App -------------------");
String property2 = System.getProperty("java.class.path");
String s2 = property2.replaceAll(";", System.lineSeparator());
System.out.println(s2);
}
}
/** */
//E:\JDK\jdk1.8\jre\lib\resources.jar
//E:\JDK\jdk1.8\jre\lib\rt.jar
//E:\JDK\jdk1.8\jre\lib\sunrsasign.jar
//E:\JDK\jdk1.8\jre\lib\jsse.jar
//E:\JDK\jdk1.8\jre\lib\jce.jar
//E:\JDK\jdk1.8\jre\lib\charsets.jar
//E:\JDK\jdk1.8\jre\lib\jfr.jar
//E:\JDK\jdk1.8\jre\classes
//----------------------------------------------
//E:\JDK\jdk1.8\jre\lib\ext
//C:\Windows\Sun\Java\lib\ext
//----------------------------------------------
//E:\JDK\jdk1.8\jre\lib\charsets.jar
//E:\JDK\jdk1.8\jre\lib\deploy.jar
//E:\JDK\jdk1.8\jre\lib\ext\access-bridge-64.jar
//E:\JDK\jdk1.8\jre\lib\ext\cldrdata.jar
//E:\JDK\jdk1.8\jre\lib\ext\dnsns.jar
//E:\JDK\jdk1.8\jre\lib\ext\jaccess.jar
//E:\JDK\jdk1.8\jre\lib\ext\jfxrt.jar
특히 주의해 야 할 것 은 이 등급 관 계 는 계승 되 지 않 은 관계 가 안에 있 고 순수한 문법 적 계승 일 뿐이다.다음 그림 은 클래스 로 딩 의 전 과정 입 니 다:
비교적 통속 적 인 말로 이 과정 을 설명 합 니 다.불 러 올 클래스 가 있 을 때 먼저 이 클래스 가 메모리 에 불 러 왔 는 지 판단 하고 불 러 올 지 여 부 를 판단 하 는 과정 은 순서 가 있 습 니 다.자신 이 정의 한 클래스 로 더 가 있 으 면 custom class loader 의 cache(캐 시)에서 불 러 왔 는 지 여 부 를 찾 습 니 다.불 러 왔 으 면 결 과 를 직접 되 돌려 줍 니 다.그렇지 않 으 면 App 의 cache 에서 찾 습 니 다.만약 에 존재 하지 않 으 면 Extension 에서 찾 습 니 다.존재 하지 않 으 면 직접 되 돌아 갑 니 다.부모 로 더 에서 Bootstrap 맨 위 까지 계속 찾 습 니 다.만약 에 찾 지 못 하면 로 더 가 이 종 류 를 불 러 온 적 이 없습니다.해당 하 는 로 더 를 불 러 와 야 합 니 다.먼저 이 클래스 가 자신의 로드 범위 내 에 있 는 지 확인 하고 결 과 를 직접 불 러 오 는 것 이 라면 계속 아래로 위임 하지 않 으 면 최 하급 까지 유추 하고 최종 적 으로 불 러 오지 못 하면 이상 Class NotFoundException 을 버 리 는 것 이 부모 위임 모델 입 니 다.
부모 위임 방식 이해 하기:
1.부모 로 더:클래스 로 더 의 로 더 도 아니 고 클래스 로 더 의 부모 로 더 도 아 닙 니 다.
package com.example.demo.classloader;
/**
*
*/
public class ParentAndChild {
public static void main(String[] args) {
//AppClassLoader
ClassLoader classLoader = ParentAndChild.class.getClassLoader();
System.out.println(classLoader);
//null AppClassLoader ExtClassLoader Bootstrap
ClassLoader appclassLoader = ParentAndChild.class.getClassLoader().getClass().getClassLoader();
System.out.println(appclassLoader);
//ExtClassLoader AppClassLoader ExtClassLoader
ClassLoader parent = ParentAndChild.class.getClassLoader().getParent();
System.out.println(parent);
//null
ClassLoader parentparent = ParentAndChild.class.getClassLoader().getParent().getParent();
System.out.println(parentparent);
//null
ClassLoader parentparentparent = ParentAndChild.class.getClassLoader().getParent().getParent().getParent();
System.out.println(parentparent);
/** */
//sun.misc.Launcher$AppClassLoader@18b4aac2
//null
//sun.misc.Launcher$ExtClassLoader@23fc625e
//null
//Exception in thread "main" java.lang.NullPointerException at com.example.demo.classloader.ParentAndChild.main(ParentAndChild.java:22)
}
}
2.부모 위임:그 작업 원 리 는 만약 에 하나의 클래스 로 더 가 클래스 로 더 요청 을 받 았 다 면 직접 불 러 오지 않 고 아래 에서 위로 올 라 가 는 최상 위 클래스 로 더 가 불 러 왔 는 지 찾 는 것 입 니 다.불 러 오 면 불 러 오지 않 아 도 됩 니 다.불 러 오지 않 았 다 면 위 에서 아래로 불 러 오 는 범위 에 속 하 는 지,속 하면 불 러 옵 니 다.만약 에 속 하지 않 으 면 아래 에 의뢰 를 하고 클래스 가 불 러 올 때 까지 성공 이 라 고 할 수 있 습 니 다.불 러 오 는 데 성공 하지 못 하면 이상 classnotfoundexeption 을 던 집 니 다.이것 을 부모 위임 이 라 고 합 니 다.3.왜 양친 위임 방식 을 해 야 합 니까?
주로 안전 을 위해 서 입 니 다.여 기 는 반증 법 을 사용 할 수 있 습 니 다.모든 종류의 로 더 가 클 라 스 를 메모리 에 불 러 올 수 있다 면 자바.lang.string 을 불 러 올 수 있 습 니 다.포장 할 때 비밀 번 호 를 String 대상 으로 저장 하고 비밀 번 호 를 몰래 자신의 메 일 로 보 내 면 안전 에 문제 가 생 길 수 있 습 니 다.
3.사용자 정의 클래스 로 더
package com.example.demo.classloader;
public class ClassLoaderByHand {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> clazz = ClassLoaderByHand.class.getClassLoader().
loadClass("com.example.demo.threaddemo.juc_002.Account");
String name = clazz.getName();
System.out.println(name);
}
}
/**
*
*/
//com.example.demo.threaddemo.juc_002.Account
코드 실행 결 과 를 보면 클래스 를 불 러 오 려 는 것 을 알 수 있 습 니 다.클래스 Loader 의 로드 클래스()방법 을 호출 하면 이 클래스 를 메모리 에 불 러 올 수 있 습 니 다.불 러 오 는 것 이 완료 되면 클래스 클래스 의 대상 을 되 돌려 줍 니 다.하 드 디스크 에서 이러한 종류의 소스 코드 를 찾 아 메모리 에 로드 하 는 동시에 Class 대상 을 생 성 합 니 다.상기 애플 릿 은 ClassLoaderby Hand 을 통 해 그의 로 더 AppClassLoader 를 찾 은 다음 에 loadclas()방법 을 호출 하여 Account 류 를 불 러 오고 clazz 대상 으로 돌아 가 며 clazz.getName()방법 으로 Account 류 를 정상적으로 되 돌려 줍 니 다.
언제 우 리 는 클래스 를 불 러 올 것 을 스스로 정의 해 야 합 니까?
열 배치 시 이전에 불 러 온 클래스 를 제거 한 다음 사용자 정의 클래스 로 더 를 다시 불 러 옵 니 다.
spring 의 동적 에이전트,새로운 class 가 필요 할 때 메모리 에 로드 합 니 다.
원본 코드 를 살 펴 보 겠 습 니 다.로 딩 과정 에서 가장 중요 한 것 은 ClassLoader 의 loaderClass()방법 입 니 다.
위 에서 준 클래스 로드 과정의 도 해 를 결합 하여 보 는 것 이 더 쉬 울 것 입 니 다.
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
/**
* findLoadedClass()
*
* null
*/
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
// Bootstrap loadClass()
if (parent != null) {
c = parent.loadClass(name, false);
} else {
// Bootstrap Class Loader,
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
//
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
// findClass()
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.