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

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

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

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]删除
最新教程 更多>
  • PHP SimpleXML解析带命名空间冒号的XML方法
    PHP SimpleXML解析带命名空间冒号的XML方法
    在php 很少,请使用该限制很大,很少有很高。例如:这种技术可确保可以通过遍历XML树和使用儿童()方法()方法的XML树和切换名称空间来访问名称空间内的元素。
    编程 发布于2025-04-28
  • Python不会对超范围子串切片报错的原因
    Python不会对超范围子串切片报错的原因
    在python中用索引切片范围:二重性和空序列索引单个元素不同,该元素会引起错误,切片在序列的边界之外没有。这种行为源于索引和切片之间的基本差异。索引一个序列,例如“示例” [3],返回一个项目。但是,切片序列(例如“示例” [3:4])返回项目的子序列。索引不存在的元素时,例如“示例” [9] ...
    编程 发布于2025-04-28
  • 如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    在Visual Studio 2012 尽管已安装了MySQL Connector v.6.5.4,但无法将MySQL数据库添加到实体框架的“ DataSource对话框”中。为了解决这一问题,至关重要的是要了解MySQL连接器v.6.5.5及以后的6.6.x版本将提供MySQL的官方Visual...
    编程 发布于2025-04-28
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式接口中实现垂直滚动元素的CSS高度限制问题:考虑一个布局,其中我们具有与用户垂直滚动一起移动的可滚动地图div,同时与固定的固定sidebar保持一致。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。$("#map").css({ marginT...
    编程 发布于2025-04-28
  • CSS强类型语言解析
    CSS强类型语言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    编程 发布于2025-04-28
  • 如何解决AppEngine中“无法猜测文件类型,使用application/octet-stream...”错误?
    如何解决AppEngine中“无法猜测文件类型,使用application/octet-stream...”错误?
    appEngine静态文件mime type override ,静态文件处理程序有时可以覆盖正确的mime类型,在错误消息中导致错误消息:“无法猜测mimeType for for file for file for [File]。 application/application/octet...
    编程 发布于2025-04-28
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-04-28
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    编程 发布于2025-04-28
  • 如何从PHP中的Unicode字符串中有效地产生对URL友好的sl。
    如何从PHP中的Unicode字符串中有效地产生对URL友好的sl。
    为有效的slug生成首先,该函数用指定的分隔符替换所有非字母或数字字符。此步骤可确保slug遵守URL惯例。随后,它采用ICONV函数将文本简化为us-ascii兼容格式,从而允许更广泛的字符集合兼容性。接下来,该函数使用正则表达式删除了不需要的字符,例如特殊字符和空格。此步骤可确保slug仅包含...
    编程 发布于2025-04-28
  • 如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    使用http request 上传文件上传到http server,同时也提交其他参数,java.net.net.urlconnection and Multipart/form-data Encoding是普遍的。 Here's a breakdown of the process:Mu...
    编程 发布于2025-04-28
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-04-28
  • 版本5.6.5之前,使用current_timestamp与时间戳列的current_timestamp与时间戳列有什么限制?
    版本5.6.5之前,使用current_timestamp与时间戳列的current_timestamp与时间戳列有什么限制?
    在时间戳列上使用current_timestamp或MySQL版本中的current_timestamp或在5.6.5 此限制源于遗留实现的关注,这些限制需要对当前的_timestamp功能进行特定的实现。 创建表`foo`( `Productid` int(10)unsigned not n...
    编程 发布于2025-04-28
  • 如何检查对象是否具有Python中的特定属性?
    如何检查对象是否具有Python中的特定属性?
    方法来确定对象属性存在寻求一种方法来验证对象中特定属性的存在。考虑以下示例,其中尝试访问不确定属性会引起错误: >>> a = someClass() >>> A.property Trackback(最近的最新电话): 文件“ ”,第1行, attributeError:SomeClass实...
    编程 发布于2025-04-28
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python import codecs import codecs import codecs 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有...
    编程 发布于2025-04-28
  • 在PHP中如何高效检测空数组?
    在PHP中如何高效检测空数组?
    在PHP 中检查一个空数组可以通过各种方法在PHP中确定一个空数组。如果需要验证任何数组元素的存在,则PHP的松散键入允许对数组本身进行直接评估:一种更严格的方法涉及使用count()函数: if(count(count($ playerList)=== 0){ //列表为空。 } 对...
    编程 发布于2025-04-28

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

Copyright© 2022 湘ICP备2022001581号-3