주제
목차
- 클래스 로더란
- 동작 원리 2가지
내용
클래스 로더

- 메모리에 없는 클래스가 필요하게 되면 파일로부터 읽어서 메모리에 로딩하는 역할을 함.
- 크게 3가지 단계로 동작
- 요청 받으면 캐시 확인
- 없으면 상위 클래스 로더 확인
- 자기 자신에 있는지 확인
- 종류 4가지
Bootstrap Class Loader : 맨 처음 , 기본 클래스 로드하고 있음
Extension Class Loader : 자바 기본 클래스에서 확장한 클래스 로드
System Class Loader : 클래스 패스 옵션으로 주어진 클래스들을 로드
사용자 정의 클래스 로더
클래스 로드 과정
- 로딩단계
- 클래스를 파일에서 가져와서 jvm 메모리 로드 단계
- 링킹 단계
- 검증 : 바이트코드가 자바 규칙에 맞는지
- 준비 : 클래스가 필요로 하는 메모리를 미리 할당하는
- 분석 : 클래스가 참조하는 객체에 실제 메모리를 주소값을 할당하는 단계
- 초기화 단계
- static 변수의 값을 할당을 한 다음에 클래스를 초기화 하는 단계
동적인 클래스 로딩이란?
- 즉, 런타임에 모든 코드가 JVM에 링크 된다.
- 모든 클래스는 그 클래스가 참조되는 순가에 동적으로 jvm에 링크되며, 메모리에 로딩된다.
- 동적인 클래스 로딩은 자바의 클래스 로더 시스템을 통해서 이루어지며, 자바가 기본적으로 제공하는 클래스로더는
java.lang.ClassLoader
를 통해서 표현된다.
- jvm이 시작되면, 부트스트랩 클래스로더를 생성하고, 그 다음에 가장 첫번째 클래스인 object를 시스템에 읽어온다.
런타임에 동적으로 클래스를 로딩한다는 것은 jvm이 클래스에 대한 정보를 갖고 있지 않다는 것을 의미
한다.
- 즉 jvm은 클래스의 메소드, 필드, 상속 관계 등에 대한 정보를 알지 못한다.
- 따라서, 클래스로더는 클래스를 로딩할 때 필요한 정보를 구하고, 그 클래스가 올바른지를 검사할 수 있어야 한다.
클래스를 로딩할 때가 아닌 코드를 실행하는 순간에 클래스를 로딩하는 것을 런타임 동적 로딩이라고 한다.
로드타임 동적 로딩(load-time dynamic loading)과 런타임 동적 로딩(run-time dynamic loading)
클래스를 로딩하는 방식에는 로드타임 동적 로딩(load-time dynamic loading)과 런타임 동적 로딩(run-time dynamic loading)이 있다. 먼저 로드타임 동적 로딩에 대해서 알아보기 위해 다음과 코드를 살펴보자.
public class HelloWorld { public static void main(String[] args) { System.out.println("안녕하세요!"); } }
HelloWorld 클래스를 실행하였다고 가정해보자. 아마도, 명령행에서 다음과 같이 입력할 것이다.
$ java HelloWorld
- JVM이 시작
- 부트스트랩 클래스로더가 생성된 후에, 모든 클래스가 상속받고 있는 Object 클래스를 읽어온다.
- 그 이후, 클래스로더는 명령행에서 지정한 HelloWorld 클래스를 로딩하기 위해, HelloWorld.class 파일을 읽는다.
- HelloWorld 클래스를 로딩하는 과정에서 필요한 클래스가 존재한다.
- 바로 java.lang.String과 java.lang.System이다. 이 두 클래스는 HelloWorld 클래스를 읽어오는 과정에서, 즉 로드타임에 로딩된다. 이 처럼, 하나의 클래스를 로딩하는 과정에서 동적으로 클래스를 로딩하는 것을 로드타임 동적 로딩이라고 한다. (extension class loader)
public class Hello1 implements Runnable { public void run() { System.out.println("안녕1"); } } public class Hello2 implements Runnable { public void run() { System.out.println("안녕2"); } } public class RuntimeLoading { public static void main(String[] args) { try { if (args.length < 1) { System.out.println("사용법: java RuntimeLoading [클래스 이름]"); System.exit(1); } Class klass = Class.forName(args[0]); Object obj = klass.newInstance(); Runnable r = (Runnable) obj; r.run(); } catch(Exception ex) { ex.printStackTrace(); } } }
- 위 코드에서, Class.forName(className)은 파리미터로 받은 className에 해당하는 클래스를 로딩한 후에, 그 클래스에 해당하는 Class 인스턴스(로딩한 클래스의 인스턴스가 아니다!)를 리턴.
- Class 클래스의 newInstance() 메소드는 Class가 나타내는 클래스의 인스턴스를 생성한다. 예를 들어, 다음과 같이 한다면 java.lang.String 클래스의 객체가 생성된다.
- 따라서, Class.forName() 메소드가 실행되기 전까지는 RuntimeLoading 클래스에서 어떤 클래스를 참조하는 지 알수 없다. 다시 말해서, RuntimeLoading 클래스를 로딩할 때는
어떤 클래스도 읽어오지 않고, RuntimeLoading 클래스의 main() 메소드가 실행되고 Class.forName(args[0])를 호출하는 순간에 비로서 args[0]에 해당하는 클래스를 읽어온다.
이처럼 클래스를 로딩할 때가 아닌코드를 실행하는 순간에 클래스를 로딩하는 것을 런타임 동적 로딩
이라 한다.
load 되는 클래스들 실제로 보기 vm option 켜기

- modify options → add vm options 클릭 후
- -verbose: class 입력
- 터미널 실행시
-verbose: class ${특정 클래스 이름 입력}