JVM은 클래스 로더

JVM이 무엇인지 첫째,

  JVM (자바 가상 머신)을 실행할 수있는 자바 바이트 코드 파일 (예 개의 .class 파일) 가상 머신 프로세스입니다. 자바 소스 파일이 성공적으로 .class 파일로 컴파일 할 수있는 경우 JVM이 파일을 다른 플랫폼에 대해 동일한 기계 코드라고 설명을 .class 수 있기 때문에, JVM은 서로 다른 플랫폼에서 서로 다른 버전을 실행할 수 있습니다. JVM을의 존재, 자바는 플랫폼 독립적 인 언어로 알려져 있기 때문이다.

  일반적으로 된 .java 파일이의 .class 파일 후 컴파일됩니다, 당신은 클래스 로더를 통과해야하기 전에 파일을 메모리로로드, 간단하게 그림을 살펴했다 :

            

둘째, 클래스 로딩 과정

  클래스 로딩 과정은 : 부하 -> 연결 (확인 -> 제조 -> 분석) -> 초기화. 여기에 몇 가지 과정을들을 수 있습니다.

 1로드

  이것은 주로 클래스의 완전한 이름 통해 예컨대 java.lang.String의 벨트 패키지로 이러한 클래스 이름 취득한 바이트 코드 파일 후 정적 저장 구조 (간단한 것으로 이해 될 수있는 바이트 코드 파일이 나타내는 템플릿 개체 생성)이 메소드 영역이고, 힙의 액세스 방법 입력 영역 "템플릿"으로,이 클래스 타입 클래스 담당자의 객체를 생성하고,이 템플릿에 따라 생성 될 때 이후의 객체를 생성한다.

  예를 들어, 때로는 반사에 의해 생성 된 객체는, 같은 객체를 생성하는 JDBC. 때 배우지 않았다 위해서, newInstance ()를 Class.getName ()에 ( "com.mysql.jdbc.Driver.class")를 통과 할 것이다 각각의 클래스 정규화 된 클래스 이름을 통해 다음 '템플릿'의 면적을 구하고에있어서, 상기 객체를 생성한다.

        

 2, 검증

  주요 검증 프로세스는로드 된 클래스의 정확성을 보장합니다. 우선은,의 .class 접미사 프로그램을 실행할 수있는 그 무엇에 해당 접미어 변화를 식별하는 경우, 파일 형식 사양 여부를 확인해야합니다, 그것은 문제가 매우 쉬울 것이다. 아마 같을 것이다 바이트 코드 파일을 살펴 보자 :

       

 

  접두사 카페 아기 주 (커피 아기?)이, 바이트 코드 파일의 유효성 검사가 메이저와 마이너 버전 번호 및 기타 인증 정보가 포함됩니다 검증 포인트의 하나입니다.

 3, 준비

  这个阶段主要是给类变量(静态变量)分配方法区的内存并初始化。实例变量不是在这个阶段分配内存,实例变量是随着对象一起分配在堆中。另外,给静态变量初始化为零值或空值,比如public static int n=5;这里并不是马上给 n 这个变量赋值为 5,而是先将其赋值为 0,类似的,如果是引用数据类型,则默认为 null。还有一点需要注意的是,对于 final 类型的数据,必须在程序内给它赋值,系统不会自动初始化,例如 static String str = "hello" + “world”;String 是 final 类型的,在编译阶段就给它优化成 static String str = "helloworld” ,并且将 "helloworld" 放进了常量池。

 4、初始化

  这个阶段就是将静态变量赋值为初始值,还是 public static int n=5; 这回给 n 赋值为 5 了。

三、类加载器

        

  启动类加载器是由C/C++写的,主要负责加载 jre\lib 目录下的类;扩展类加载器主要负责加载 jre\lib\ext 目录下的类;而应用程序类加载器主要负责加载我们自己编写的类;当然还能自己写类加载器,即自定义加载器。程序主要由前面三个类加载器相互配合加载的。

public class Main {
    public static void main(String[] args) {
        Main main = new Main();
        System.out.println(main.getClass().getClassLoader());
        System.out.println(main.getClass().getClassLoader().getParent());
        System.out.println(main.getClass().getClassLoader().getParent().getParent());
    }
}  

  由于启动类加载器是 C/C++ 语言写的,所以输出为 null

 双亲委派机制

  在类加载的过程中,存在着双亲委派机制,即当要加载一个类时,先由父类加载器加载,当父类加载器没办法加载时,才由下面的加载器加载,来看一个程序:

package java.lang;   // 自定义的包

public class String {
    public static void main(String[] args) {
        System.out.println("这是自定义的java.lang.String类");
    }
}

  

  由于 jre\lib\ext 中存在 java.lang.String 类,当加载该类的时候,根据全限定名进行查找,找到后由启动类加载器加载,发现 String 类中不包含 main() 方法,因此程序出错。 

추천

출처www.cnblogs.com/lyuzt/p/12057385.html