

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 自訂 Lambda 函數的 Java 執行時期啟動行為
<a name="java-customization"></a>

此頁面說明 中 Java 函數的特定設定 AWS Lambda。您可以使用這些設定來自訂 Java 執行期啟動行為。這可以減少整體函數延遲並提高整體函數效能，而無需修改任何程式碼。

**Topics**
+ [了解 `JAVA_TOOL_OPTIONS` 環境變數](#java-tool-options)
+ [Log4Shell 的 Log4j 修補程式 Log4Shell](#log4shell-patch)
+ [Ahead-of-Time(AOT) 和 CDS 快取](#aot-cds-caches)

## 了解 `JAVA_TOOL_OPTIONS` 環境變數
<a name="java-tool-options"></a>

在 Java 中，Lambda 支援 `JAVA_TOOL_OPTIONS` 環境變數，以在 Lambda 中設定其他命令列變數。您可以透過各種方式使用此環境變數，例如自訂分層編譯設定。下一個範例將示範如何針對此使用案例使用 `JAVA_TOOL_OPTIONS` 環境變數。

### 範例：自訂分層編譯設定
<a name="tiered-compilation"></a>

分層編譯是 Java 虛擬機器 (JVM) 的功能。您可以使用特定的分層編譯設定來充分利用 JVM 的即時 (JIT) 編譯器。通常，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 預設會將 JVM 設定為停止層級 1 的分層編譯。從 Java 25 開始，Lambda 預設仍會停止層級 1 的分層編譯，除非在使用 SnapStart 或佈建並行時，在這種情況下會使用預設 JVM 設定。這可改善 SnapStart 和佈建並行的效能，而不會產生冷啟動懲罰，因為分層編譯在這些情況下是在調用路徑之外執行。若要最大化此優點，您可以在 SnapStart 快照之前或預先佈建佈建並行執行環境時，使用 priming - 在函數初始化期間執行程式碼路徑來觸發 JIT。如需詳細資訊，請參閱部落格文章[，使用進階入門策略搭配 SnapStart 最佳化 AWS Lambda 的冷啟動效能](https://aws.amazon.com/blogs/compute/optimizing-cold-start-performance-of-aws-lambda-using-advanced-priming-strategies-with-snapstart/)。

**自訂分層編譯設定 (主控台)**

1. 開啟 Lambda 主控台中的[函數](https://console.aws.amazon.com/lambda/home#/functions)頁面。

1. 選擇您要自訂分層編譯的 Java 函數。

1. 選擇**組態**索引標籤，然後選擇左側選單中的**環境變數**。

1. 選擇**編輯**。

1. 選擇 **Add environment variable** (新增環境變數)。

1.  針對索引鍵，輸入 `JAVA_TOOL_OPTIONS`。針對值，輸入 `-XX:+TieredCompilation -XX:TieredStopAtLevel=1`。  
![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/java-tool-options-tiered-compilation.png)

1. 選擇**儲存**。

**注意**  
您也可以使用 Lambda SnapStart 來解決冷啟動問題。SnapStart 會使用執行環境的快取快照來顯著改善啟動效能。如需有關 SnapStart 功能、限制和支援區域的詳細資訊，請參閱[使用 Lambda SnapStart 改善啟動效能](snapstart.md)。

### 範例：使用 JAVA\$1TOOL\$1OPTIONS 自訂 GC 行為
<a name="gc-behavior"></a>

Java 11 執行期使用[串行](https://docs.oracle.com/en/java/javase/18/gctuning/available-collectors.html#GUID-45794DA6-AB96-4856-A96D-FDE5F7DEE498)垃圾回收器 (GC) 進行垃圾回收。依預設，Java 17 執行期也會使用串行垃圾回收器。但是，對於 Java 17，您也可以使用 `JAVA_TOOL_OPTIONS` 環境變數來變更預設垃圾回收器。可以在並行垃圾回收器和 [Shenandoah](https://wiki.openjdk.org/display/shenandoah/Main) 垃圾回收器之間進行選擇。

例如，如果工作負載使用更多記憶體和多個 CPU，則請考慮使用並行垃圾回收器以獲得更好的效能。可以透過將下列內容附加到 `JAVA_TOOL_OPTIONS` 環境變數的值來執行此操作：

```
-XX:+UseParallelGC
```

如果您的工作負載有許多短期物件，您可以透過啟用 Java 25 中引入的 Shenandoah 垃圾收集器的世代模式，從較低的記憶體耗用中獲益。若要執行此作業，請將下列項目附加至`JAVA_TOOL_OPTIONS`環境變數的值：

```
-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational
```

## Log4Shell 的 Log4j 修補程式 Log4Shell
<a name="log4shell-patch"></a>

Java 8、11、17 和 21 的 Lambda 執行時間包含修補程式，可減輕 Log4Shell 漏洞 (CVE-2021-44228)，Log4j熱門的 Java 記錄架構。此修補程式會產生冷啟動效能額外負荷。如果您使用的是修補程式版本的 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 快取
<a name="aot-cds-caches"></a>

從 Java 25 開始，Lambda 執行時間包含 Java 執行時間界面用戶端 (RIC) Ahead-of-Time (AOT) 快取，這是一種執行時間元件，可主動輪詢來自 Lambda 執行時間 API 的事件。這可改善冷啟動效能。

AOT 快取專屬於 JVM 組建。當 Lambda 更新受管執行期時，也會更新 RIC 的 AOT 快取。不過，如果您部署自己的 AOT 快取，這些快取可能會失效，或在執行時間更新後導致意外行為。因此，強烈建議在使用受管執行期時不要使用 AOT 快取。若要使用 AOT 快取，您應該使用容器映像部署函數。

AOT 快取無法與類別資料共用 (CDS) 快取搭配使用。如果您在 Lambda 函數中部署 CDS 快取，則 Lambda 會停用 AOT 快取。