Lambda 함수의 Java 런타임 시작 동작에 대한 사용자 지정
이 페이지에서는 AWS Lambda의 Java 함수와 관련된 설정을 설명합니다. 이러한 설정을 사용하여 Java 런타임 시작 동작을 사용자 지정할 수 있습니다. 이를 통해 코드를 수정하지 않고도 전체 함수 지연 시간을 줄이고 전체 함수 성능을 개선할 수 있습니다.
JAVA_TOOL_OPTIONS 환경 변수에 대한 이해
Java에서 Lambda는 Lambda에서 추가 명령줄 변수를 설정할 수 있도록 JAVA_TOOL_OPTIONS 환경 변수를 지원합니다. 계층형 컴파일 설정을 사용자 지정하는 등 다양한 방식으로 이 환경 변수를 사용할 수 있습니다. 다음 예제에서는 이 사용 사례에 JAVA_TOOL_OPTIONS 환경 변수를 사용하는 방법을 설명합니다.
예제: 계층형 컴파일 설정에 대한 사용자 지정
계층형 컴파일은 Java 가상 머신(JVM)의 기능입니다. 특정 계층형 컴파일 설정을 사용하여 JVM의 JIT(Just-In-Time) 컴파일러를 최대한 활용할 수 있습니다. 일반적으로 C1 컴파일러는 빠른 시작 시간에 최적화되어 있습니다. C2 컴파일러는 최상의 전체 성능에 최적화되어 있지만 더 많은 메모리를 사용하고 이를 달성하는 데 더 오랜 시간이 걸립니다. 계층형 컴파일에는 5가지 수준이 있습니다. 수준 0에서 JVM은 Java 바이트 코드를 해석합니다. 수준 4에서 JVM은 C2 컴파일러를 사용하여 애플리케이션 시작 중 수집된 프로파일링 데이터를 분석합니다. 시간 경과에 따라 코드 사용을 모니터링하여 최상의 최적화를 식별합니다.
계층형 컴파일 수준을 사용자 지정하면 Java 함수 성능을 조정할 수 있습니다. 빠르게 실행되는 소규모 함수의 경우 계층형 컴파일을 레벨 1로 설정하면 JVM이 C1 컴파일러를 사용하도록 하여 콜드 스타트 성능을 개선할 수 있습니다. 이 설정은 최적화된 네이티브 코드를 빠르게 생성하지만 프로파일링 데이터를 생성하지 않으며 C2 컴파일러를 사용하지 않습니다. 컴퓨팅 집약적인 대규모 함수의 경우 계층형 컴파일을 레벨 4로 설정하면 각 Lambda 실행 환경이 프로비저닝된 후 첫 번째 간접 호출 중에 추가 메모리 소비 및 추가 최적화 작업을 희생하면서 전체 성능이 극대화됩니다.
Java 11 런타임 이하의 경우 Lambda는 기본 JVM 계층형 컴파일 설정을 사용합니다. Java 17 및 Java 21의 경우 Lambda는 기본적으로 레벨 1에서 계층형 컴파일을 중지하도록 JVM을 구성합니다. Java 25에서 Lambda는 기본 JVM 설정이 사용되는 SnapStart 또는 프로비저닝 동시성을 사용하는 경우를 제외하고 기본적으로 레벨 1에서 계층형 컴파일을 계속 중지합니다. 이를 통해 계층형 컴파일이 간접 호출 경로 외부에서 수행되므로 콜드 스타트 페널티가 발생하지 않고 SnapStart 및 프로비저닝 동시성의 성능이 개선됩니다. 이 이점을 극대화하기 위해 SnapStart 스냅샷을 생성하기 전에 또는 프로비저닝 동시성 실행 환경이 사전 프로비저닝될 때 함수 초기화 중에 코드 경로를 실행하여 JIT를 트리거하는 준비 작업을 사용할 수 있습니다. 자세한 내용은 블로그 게시물 Optimizing cold start performance of AWS Lambda using advanced priming strategies with SnapStart
계층형 컴파일 설정 사용자 지정(콘솔)
-
Lambda 콘솔에서 함수
페이지를 엽니다. -
계층형 컴파일을 사용자 지정하려는 Java 함수를 선택합니다.
-
구성 탭을 선택한 다음 왼쪽 메뉴에서 환경 변수를 선택합니다.
-
편집을 선택합니다.
-
Add environment variable(환경 변수 추가)을 선택합니다.
-
키로
JAVA_TOOL_OPTIONS를 입력합니다. 값으로-XX:+TieredCompilation -XX:TieredStopAtLevel=1을 입력합니다.
-
저장을 선택합니다.
참고
Lambda SnapStart를 사용하여 콜드 스타트 문제를 완화할 수도 있습니다. SnapStart는 실행 환경의 캐시된 스냅샷을 사용하여 시작 성능을 크게 향상시킵니다. SnapStart 기능, 제한 사항 및 지원되는 리전에 대한 자세한 내용은 Lambda SnapStart를 사용하여 시작 성능 개선 섹션을 참조하세요.
예: JAVA_TOOL_OPTIONS를 사용하여 GC 동작 사용자 지정
Java 11 런타임은 가비지 수집을 위해 직렬JAVA_TOOL_OPTIONS 환경 변수를 사용하여 기본 GC를 변경할 수도 있습니다. 병렬 GC와 Shenandoah GC
예를 들어 워크로드에 더 많은 메모리와 여러 CPU를 사용하는 경우 병렬 GC를 사용하여 성능을 향상시킬 수 있습니다. JAVA_TOOL_OPTIONS 환경 변수 값에 다음을 추가하여 이 작업을 수행할 수 있습니다.
-XX:+UseParallelGC
워크로드에 수명이 짧은 객체가 많은 경우 Java 25에 도입된 Shenandoah 가비지 수집기의 세대 모드를 활성화하여 메모리 소비량을 줄일 수 있습니다. 이를 위해 JAVA_TOOL_OPTIONS 환경 변수 값에 다음을 추가합니다.
-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational
Log4Shell용 Log4j 패치
Java 8, 11, 17 및 21용 Lambda 런타임에는 자주 사용되는 Java 로깅 프레임워크인 Log4j에서 Log4Shell 취약성(CVE-2021-44228)을 완화하는 패치가 포함되어 있습니다. 이 패치를 통해 콜드 스타트 성능 오버헤드가 발생합니다. 패치된 버전의 Log4j(버전 2.17.0 이상)를 사용하는 경우 이 패치를 비활성화하여 콜드 스타트 성능을 개선할 수 있습니다. 패치를 비활성화하려면 AWS_LAMBDA_DISABLE_CVE_2021_44228_PROTECTION 환경 변수를 true로 설정합니다.
Java 25부터 Lambda 런타임에는 더 이상 Log4Shell 패치가 포함되지 않습니다. Log4j 버전 2.17.0 이상을 사용해야 합니다.
Ahead-of-Time(AOT) 및 CDS 캐시
Java 25부터 Lambda 런타임에는 Lambda 런타임 API의 이벤트를 적극적으로 폴링하는 런타임 구성 요소인 Java 런타임 인터페이스 클라이언트(RIC)에 대한 Ahead-of-Time(AOT) 캐시가 포함되어 있습니다. 이를 통해 콜드 스타트 성능이 개선됩니다.
AOT 캐시는 JVM 빌드에만 해당됩니다. Lambda가 관리형 런타임을 업데이트할 때 RIC에 대한 AOT 캐시도 업데이트합니다. 하지만 자체 AOT 캐시를 배포하는 경우 이러한 캐시가 무효화되거나 런타임 업데이트 후 예기치 않은 동작이 발생할 수 있습니다. 따라서 관리형 런타임을 사용하는 경우 AOT 캐시를 사용하지 않는 것이 좋습니다. AOT 캐시를 사용하려면 컨테이너 이미지를 사용하여 함수를 배포해야 합니다.
AOT 캐시를 클래스 데이터 공유(CDS) 캐시와 함께 사용할 수는 없습니다. Lambda 함수에 CDS 캐시를 배포하면 Lambda는 AOT 캐시를 비활성화합니다.