자바에서 클래스 정보는 어떻게 알아낼 수 있을까?
자바에서 클래스 정보를 가져오기 위해서 Reflection API를 사용할 수 있습니다. reflection 패키지에서 제공하는 클래스를 사용하면, JVM에 로딩되어 있는 클래스와 메서드의 정보를 읽어올 수 있습니다. 대표적으로 Class 클래스, Method 클래스, Field 클래스가 존재합니다.
Reflection API를 사용하면 구체적인 클래스의 타입을 몰라도, 클래스의 정보에 접근할 수 있습니다. 개발자는 이러한 특성을 이용하여 인스턴스를 감싸는 프록시를 만들거나, 사용자로부터 전달된 값을 처리할 메서드를 유연하게 선택하는 등 다양한 구현을 할 수 있습니다. Reflection API는 특히 프레임워크나 라이브러리를 개발하는 과정에서 사용되는 경우가 많습니다. 프레임워크나 라이브러리의 개발자는 사용자가 작성한 클래스에 대한 정보를 알 수 없기 때문입니다.
✔️ Reflection API 단점
Reflection API는 동적으로 클래스의 정보에 접근할 수 있다는 점에서 강력한 기능입니다. 하지만, 일반적인 코드보다 복잡한 코드가 필요할 수 있습니다. 또한, 캡슐화가 약화되어 강결합으로 이어질 수 있습니다. 일반적인 메서드 호출과 Method 클래스의 invoke 호출의 성능을 비교했을 때, JIT 최적화가 어려워질 수 있어 일반적인 메서드 호출보다 성능이 저하될 가능성이 있습니다. 단, 이 부분은 사용 중인 JVM의 버전과 프로그램 상황에 따라 다를 수 있습니다.
✔️ JIT(Just-In-Time) 컴파일이란?
바이트코드(중간 언어)를 프로그램 실행 중에 네이티브 코드(기계어)로 변환하여 실행 성능을 높이는 기술입니다.
JVM(Java Virtual Machine) 또는 CLR(Common Language Runtime) 내부에 존재하며, 해석기(Interpreter)의 느린 실행 속도를 보완하면서도, 컴파일 언어 수준의 성능을 추구합니다.
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 1_000_000; i++) {
compute();
}
}
public static void compute() {
int x = 1 + 2;
}
}
👉🏻 compute()는 반복적으로 호출되며, JIT에 의해 기계어로 변환될 가능성이 큽니다.
JIT의 작동 방식
- Java 소스 → 바이트코드(.class 파일)
- JVM이 바이트코드를 실행
- 특정 메서드가 반복 호출되면 → JIT이 해당 메서드를 기계어로 컴파일
- 다음부터는 기계어로 직접 실행 → 빠름!
장점
- 빠른 실행 속도 (해석보다 빠름)
- 런타임 최적화 가능 (HotSpot JIT 등은 자주 쓰이는 경로만 집중적으로 최적화)
- 플랫폼 독립성 유지: 컴파일은 런타임에 하므로 JVM만 맞으면 어디서든 실행 가능
단점
- 초기 실행 속도 느림 (JIT 컴파일 자체도 시간이 걸림)
- 메모리 사용 증가
- 예측 불가능한 GC나 JIT 타이밍 이슈