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

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

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

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]删除
最新教程 更多>
  • Java中假唤醒真的会发生吗?
    Java中假唤醒真的会发生吗?
    在Java中的浪费唤醒:真实性或神话?在Java同步中伪装唤醒的概念已经是讨论的主题。尽管存在这种行为的潜力,但问题仍然存在:它们实际上是在实践中发生的吗? Linux的唤醒机制根据Wikipedia关于伪造唤醒的文章,linux实现了pthread_cond_wait()功能的Linux实现,利用...
    编程 发布于2025-05-01
  • Java是否允许多种返回类型:仔细研究通用方法?
    Java是否允许多种返回类型:仔细研究通用方法?
    在Java中的多个返回类型:一种误解类型:在Java编程中揭示,在Java编程中,Peculiar方法签名可能会出现,可能会出现,使开发人员陷入困境,使开发人员陷入困境。 getResult(string s); ,其中foo是自定义类。该方法声明似乎拥有两种返回类型:列表和E。但这确实是如此吗...
    编程 发布于2025-05-01
  • 如何使用Depimal.parse()中的指数表示法中的数字?
    如何使用Depimal.parse()中的指数表示法中的数字?
    在尝试使用Decimal.parse(“ 1.2345e-02”中的指数符号表示法表示的字符串时,您可能会遇到错误。这是因为默认解析方法无法识别指数符号。 成功解析这样的字符串,您需要明确指定它代表浮点数。您可以使用numbersTyles.Float样式进行此操作,如下所示:[&& && && ...
    编程 发布于2025-05-01
  • 在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    编程 发布于2025-05-01
  • 如何在Chrome中居中选择框文本?
    如何在Chrome中居中选择框文本?
    选择框的文本对齐:局部chrome-inly-ly-ly-lyly solument 您可能希望将文本中心集中在选择框中,以获取优化的原因或提高可访问性。但是,在CSS中的选择元素中手动添加一个文本 - 对属性可能无法正常工作。初始尝试 state)</option> < op...
    编程 发布于2025-05-01
  • 在JavaScript中如何并发运行异步操作并正确处理错误?
    在JavaScript中如何并发运行异步操作并正确处理错误?
    同意操作execution 在执行asynchronous操作时,相关的代码段落会遇到一个问题,当执行asynchronous操作:此实现在启动下一个操作之前依次等待每个操作的完成。要启用并发执行,需要进行修改的方法。 第一个解决方案试图通过获得每个操作的承诺来解决此问题,然后单独等待它们: co...
    编程 发布于2025-05-01
  • 图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    在chrome 中删除一个频繁的问题时,在与Chrome and IE9中的图像一起工作时,遇到了一个频繁的问题。和“边境:无;”在CSS中。要解决此问题,请考虑以下方法: Chrome具有忽略“ border:none; none;”的已知错误,风格。要解决此问题,请使用以下CSS ID块创建带...
    编程 发布于2025-05-01
  • Python中何时用"try"而非"if"检测变量值?
    Python中何时用"try"而非"if"检测变量值?
    使用“ try“ vs.” if”来测试python 在python中的变量值,在某些情况下,您可能需要在处理之前检查变量是否具有值。在使用“如果”或“ try”构建体之间决定。“ if” constructs result = function() 如果结果: 对于结果: ...
    编程 发布于2025-05-01
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html &lt;/main&gt; &lt;section&gt; { display:grid; grid-template-...
    编程 发布于2025-05-01
  • 如何在无序集合中为元组实现通用哈希功能?
    如何在无序集合中为元组实现通用哈希功能?
    在未订购的集合中的元素要纠正此问题,一种方法是手动为特定元组类型定义哈希函数,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    编程 发布于2025-05-01
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-05-01
  • 如何从2D数组中提取元素?使用另一数组的索引
    如何从2D数组中提取元素?使用另一数组的索引
    Using NumPy Array as Indices for the 2nd Dimension of Another ArrayTo extract specific elements from a 2D array based on indices provided by a second ...
    编程 发布于2025-05-01
  • Python中嵌套函数与闭包的区别是什么
    Python中嵌套函数与闭包的区别是什么
    嵌套函数与python 在python中的嵌套函数不被考虑闭合,因为它们不符合以下要求:不访问局部范围scliables to incling scliables在封装范围外执行范围的局部范围。 make_printer(msg): DEF打印机(): 打印(味精) ...
    编程 发布于2025-05-01
  • 如何将PANDAS DataFrame列转换为DateTime格式并按日期过滤?
    如何将PANDAS DataFrame列转换为DateTime格式并按日期过滤?
    Transform Pandas DataFrame Column to DateTime FormatScenario:Data within a Pandas DataFrame often exists in various formats, including strings.使用时间数据时...
    编程 发布于2025-05-01
  • 如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    How to Resolve "General error: 2006 MySQL server has gone away" While Inserting RecordsIntroduction:Inserting data into a MySQL database can...
    编程 发布于2025-05-01

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

Copyright© 2022 湘ICP备2022001581号-3