在本系列的前几部分中,我们测量了在未启用 SnapStart 的情况下使用 Java 21 运行时、启用 SnapStart 的 Lambda 函数的冷启动,并使用不同的 Lambda 内存设置、Lambda 部署工件大小、Java 应用了 DynamoDB 调用启动优化编译选项、(a)同步 HTTP 客户端以及不同 Lambda 层的使用。 对于所有这些测量,我们使用默认的垃圾收集算法 G1。
在本文中,我们希望探讨 Java 垃圾收集算法对 Java 21 运行时的 Lambda 函数性能的影响。我们还将重新测量 G1 的所有内容,以便与所有垃圾收集算法使用的相同次要 Java 21 版本获得可比较的结果。
对于我们的测量,我们将使用以下 Java 收集算法及其默认设置(请参阅链接文档以获取有关每种算法的更多详细信息):
在我们的实验中,我们将使用第 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 请求,性能结果与预期更加接近。
请参阅每种垃圾收集算法的文档来调整混合和最大内存等设置,这可以显着提高性能并进行您自己的测量。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3