”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > AWS SnapStart - 使用不同的垃圾收集算法通过 Java 测量冷启动和热启动的部分

AWS SnapStart - 使用不同的垃圾收集算法通过 Java 测量冷启动和热启动的部分

发布于2024-11-01
浏览:242

AWS SnapStart - Part Measuring cold and warm starts with Java using different garbage collection algorithms

介绍

在本系列的前几部分中,我们测量了在未启用 SnapStart 的情况下使用 Java 21 运行时、启用 SnapStart 的 Lambda 函数的冷启动,并使用不同的 Lambda 内存设置、Lambda 部署工件大小、Java 应用了 DynamoDB 调用启动优化编译选项、(a)同步 HTTP 客户端以及不同 Lambda 层的使用。 对于所有这些测量,我们使用默认的垃圾收集算法 G1。

在本文中,我们希望探讨 Java 垃圾收集算法对 Java 21 运行时的 Lambda 函数性能的影响。我们还将重新测量 G1 的所有内容,以便与所有垃圾收集算法使用的相同次要 Java 21 版本获得可比较的结果。

Java 垃圾收集算法

对于我们的测量,我们将使用以下 Java 收集算法及其默认设置(请参阅链接文档以获取有关每种算法的更多详细信息):

  • 垃圾优先 (G1) 垃圾收集器。这是默认使用的垃圾收集算法。您可以在 AWS SAM 模板中显式设置它,方法是将 -XX: UseG1GC 添加到 JAVA_TOOL_OPTIONS 环境变量。
  • 并行收集器。您可以在 AWS SAM 模板中显式设置它,方法是将 -XX: UseParallelGC 添加到 JAVA_TOOL_OPTIONS 环境变量。
  • 谢南多厄GC。 Oracle JDK 不提供它,但 Amazon Corretto 21 JDK 提供。您可以在 AWS SAM 模板中显式设置它,方法是将 -XX: UseShenandoahGC 添加到 JAVA_TOOL_OPTIONS 环境变量。
  • Z 垃圾收集器。有 2 种不同的 ZGC 算法:默认算法和较新的一代算法。您可以在 AWS SAM 模板中显式设置它,方法是将 -XX: UseZGC 或 -XX: UseZGC -XX: ZGenerational 添加到 JAVA_TOOL_OPTIONS 环境变量。

使用不同的垃圾收集算法测量 Java 21 的冷启动和热启动

在我们的实验中,我们将使用第 9 部分中介绍的稍作修改的应用程序。您可以在此处查找应用程序代码。基本上有 2 个 Lambda 函数,它们既响应 API 网关请求,又通过 DynamoDB 从 API 网关收到的 ID 检索产品。第一个 Lambda 函数 GetProductByIdWithPureJava21LambdaWithGCAlg 可以在有或没有 SnapStart 的情况下使用,第二个 GetProductByIdWithPureJava21LambdaAndPrimingWithGCAlg 使用 SnapStart 和 DynamoDB 请求调用启动。

下面的实验结果基于重现超过 100 次冷启动和大约 100,000 次热启动,实验运行时间约为 1 小时。为此(以及我上一篇文章中的实验),我使用了负载测试工具嘿,但是您可以使用任何您想要的工具,例如 Serverless-artillery 或 Postman。我们通过为 Lambda 函数提供 1024 MB 内存并使用 JAVA_TOOL_OPTIONS 来运行实验:“-XX: TieredCompilation -XX:TieredStopAtLevel=1”(不进行分析的 Java 客户端编译),这在冷启动时间和热启动时间之间具有非常好的权衡。

不幸的是,我无法使 Lambda 函数以 Z 垃圾收集器(默认的和一代的)启动,并遇到错误:

Failed to commit memory (Operation not permitted)
[error][gc] Forced to lower max Java heap size from 872M(100%) to 0M(0%)
[error][gc] Failed to allocate initial Java heap (512M)
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

它尝试了更大的内存设置,如 1024、2048 MB 甚至更多 MB,但仍然出现相同的错误。

让我们看看其他 3 种垃圾收集算法的测量结果。

缩写c表示冷启动,w表示热启动。

未启用 SnapStart 的冷 (c) 和热 (w) 启动时间(以毫秒为单位):

GC算法 c p50 c p75 c p90 c p99 c p99.9 c 最大值 w p50 w p75 w p90 w p99 w p99.9 w 最大值
G1 3655.17 3725.25 3811.88 4019.25 4027.30 4027.83 5.46 6.10 7.10 16.79 48.06 1929.79
并行收集器 3714.10 3789.09 3857.87 3959.44 4075.89 4078.25 5.55 6.20 7.10 15.38 130.13 2017.92
谢南多厄 3963.40 4019.25 4096.30 4221.00 4388.78 4390.76 5.82 6.45 7.39 17.06 71.02 2159.21

启用 SnapStart 且未启动的冷 (c) 和热 (w) 启动时间(以毫秒为单位):

GC算法 c p50 c p75 c p90 c p99 c p99.9 c 最大值 w p50 w p75 w p90 w p99 w p99.9 w 最大值
G1 1867.27 1935.68 2152.02 2416.57 2426.25 2427.35 5.47 6.11 7.05 17.41 51.24 1522.04
并行收集器 1990.62 2047.12 2202.07 2402.12 2418.99 2419.32 5.68 6.35 7.45 18.04 147.83 1577.21
谢南多厄 2195.47 2301.07 2563.37 3004.89 3029.01 3030.36 5.73 6.41 7.51 17.97 75.00 1843.34

启用 SnapStart 并调用 DynamoDB 启动的冷 (c) 和热 (w) 启动时间(以毫秒为单位):

GC算法 c p50 c p75 c p90 c p99 c p99.9 c 最大值 w p50 w p75 w p90 w p99 w p99.9 w 最大值
G1 833.50 875.34 1089.53 1205.26 1269.56 1269.8 5.46 6.10 7.16 16.39 46.19 499.13
并行收集器 900.18 975.12 1058.41 1141.94 1253.17 1253.99 5.82 6.61 7.75 16.87 49.64 487.73
谢南多厄 1065.84 1131.71 1331.96 1473.44 1553.59 1554.95 5.77 6.40 7.39 17.20 65.06 500.48

结论

在本文中,我们探讨了 Java 垃圾收集算法(G1、Parallel Collector 和 Shenandoah)对 Java 21 运行时的 Lambda 函数性能的影响。我们发现这些算法的性能存在很大差异。使用 G1(默认设置)的默认设置,我们会经历(有时是迄今为止)最低的冷启动和热启动时间。通过使用 SnapStart 启动 DynamoDB 请求,性能结果与预期更加接近。

请参阅每种垃圾收集算法的文档来调整混合和最大内存等设置,这可以显着提高性能并进行您自己的测量。

版本声明 本文转载于:https://dev.to/aws-builders/aws-snapstart-part-26-measuring-cold-and-warm-starts-with-java-21-using-different-garbage-collection-algorithms-8h3?1如有侵犯,请联系[email protected]删除
最新教程 更多>

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3