자바 리플렉션
리플렉션이란?
사전적 의미로는 ‘반사’라는 뜻을 가지고 있으며, 자바에서는 런타임 단계에서 클래스, 메서드 등의 정보를 얻어오는 기술을 뜻한다. 연못에 형상이 반사되어 비치듯이, 투영된 클래스의 정보를 얻어온다는 의미로 이러한 이름이 붙은게 아닌가 싶다.
리플렉션을 활용하는 대표적인 사례로는 Jackson과 같이 객체를 매핑해주는 라이브러리가 있다. 리플렉션으로 클래스의 정보를 받아와 getter를 찾은 후 json 형식으로 변환해주는 등의 역할을 수행하고 있다.
작동 원리
먼저 자바 코드를 컴파일하고 바이트코드에 해당되는 .class 파일을 생성한다. 그리고 클래스로더는 런타임동안 동적으로 클래스를 읽어온다.
런타임에 동적으로 클래스를 로딩하기 위해서는 해당 클래스에 대한 정보를 읽어올 때 검증을 하기 위한 정보를 얻을 수단이 필요했다. 만약 이런 유효성 검증 절차가 존재하지 않는다면 .class 파일의 버전 불일치 등 올바른 클래스를 가져왔는지 알 수 없는 문제가 발생한다.
이를 해결하기 위해 jvm 내부에는 클래스 분석 기능이 존재하며, jdk 1.1부터는 자바 개발자 또한 리플렉션을 이용해 클래스의 분석을 할 수 있도록 하고 있다.
네이티브 이미지와 리플렉션
최근 GraalVM은 네이티브 이미지를 지원하기 시작했다.
네이티브 이미지는 기존에 런타임 환경에서 JIT 컴파일러를 통해 작동하던 자바 코드를 바이너리 실행 파일로 ahead of time(미리) 컴파일하는 기술이다.
기존 JIT(just-in-time) 컴파일러를 이용한 방식은 런타임 중에 컴파일을 수행하는 방식이었다.
이러한 방식은 런타임 중에 지속적인 최적화를 수행하기 때문에 초기 구동 시 느린 부팅 속도 및 퍼포먼스 저하 이슈가 있었다.
이를 극복하기 위해 AoT(ahead-of-time) 컴파일러가 탄생했다.
AOT 컴파일러는 자바 바이트코드를 컴파일, 실행 파일을 만들어준다. 이런 방식은 굉장히 빠른 첫 실행 속도를 자랑하지만 런타임 최적화가 진행되지 않고, 정적으로 실행 파일을 생성하다보니 리플렉션과 같은 동적 기술에 많은 제약을 받게 되었다.
참고
Hudi, 자바 리플렉션 (Reflection) 기초, https://hudi.blog/java-reflection/
Baeldung, Guide to Java Reflection, https://www.baeldung.com/java-reflection
호호맨, 리플렉션 (reflection) 개념 이해하기, https://ebabby.tistory.com/4
IBM Developer, JITServer - Optimize your Java cloud-native applications, https://developer.ibm.com/articles/jitserver-optimize-your-java-cloud-native-applications/
자바캔, 클래스로더 1, 동적인 클래스 로딩과 클래스로더, https://javacan.tistory.com/entry/1
망나니개발자, GraalVM이 제공하는 네이티브 이미지(Native Image), https://mangkyu.tistory.com/302