调优:在 Java 中字符串重复数据删除性能
字符串重复数据删除是一项重要功能,旨在通过从堆内存中消除重复字符串来优化内存使用。然而,最近的观察表明了一个令人担忧的趋势 – 较新的 Java 版本的字符串重复数据删除性能下降。因此,我们开始进行比较分析,以评估 Java 版本 11、17 和 21 中的字符串重复数据删除性能行为。这篇文章旨在分享我们从这次分析中收集到的观察和见解。
WebCrawler Spring Boot 应用程序为了试验字符串重复数据删除,我们使用了在 Spring Boot 中开发的开源 Web Crawler 应用程序。网络爬虫是一个基于 REST 的应用程序,它将爬取任何给定的网站并将该站点的信息存档到 H2 数据库中。当发出 HTTP POST 请求时,WebCrawler 将在网站上启动爬网作业并返回 jobId。此 jobId 可以稍后用于查询爬网任务的状态。
启用字符串去重要研究字符串重复数据删除的行为,必须首先在 JVM 中启用它。这可以通过传递以下 JVM 参数来实现:
-XX:+UseStringDeduplication
-Xlog:stringdedup*=debug:file=string-dup-logfile.log -Xloggc:string-dup-logfile.log
有关 JVM 参数的详细信息,请参阅此文章 字符串重复数据删除.
JMeter 负载测试我们使用 JMeter 对 WebCrawler 应用程序进行了负载测试,模拟了 50 个用户提交具有相同种子 URL 和深度的爬取任务的负载,持续大约 1 小时。我们提交相同的 URL,以便在应用程序中模拟大量重复的字符串。
请注意,此测试是在我的本地笔记本电脑上进行的,其配置为:
操作系统:Windows 11 系统类型:64 位操作系统,基于 x64 的处理器 RAM:12 GB 处理器:Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz 1.19 GHzJava 堆大小(即 -XM512MB)
下图显示了上述情况下的 JMeter 配置:
图片图:JMeter 中的 POST 方法配置垃圾收集分析研究完成测试后,我们将生成的 Garbage Collection 日志文件上传到在线 GCeasy 工具进行分析。该工具迅速生成报告,展示每个测试的 Java 版本的字符串重复数据删除性能指标
不同 Java 版本的字符串重复数据删除关键指标的比较研究下表总结了 Java 版本中的字符串重复数据删除关键指标:
爪哇 11 爪哇 17 爪哇 21 检查的字符串 1,540,837 997,693 650,245 已删除重复的字符串 1,342,865 505,376 299,261 去重大小 102.4 兆字节 39.57 兆字节 15.81 兆字节去重百分比 34.3 % 9.3 % 3.4 %去重时间 1,264.442 毫秒 2,323.492 毫秒 3,439.466 毫秒分析显示,Java 11 表现出最佳的字符串重复数据删除性能,消除了 34.3% 的字符串。相反,Java 17 和 21 分别仅淘汰了 9.3% 和 3.4%。此外,在现代 Java 版本中,删除重复字符串所需的时间有所增加,Java 11 仅用了 1264.442 毫秒就完成了这个过程,而 Java 17 和 Java 21 分别用了 2323.492 毫秒和 3439.466 毫秒。
从本质上讲,现代 JVM 花费了更多时间来检查更多的字符串,同时从内存中消除更少的重复项。这凸显了 JVM 性能的明显下降。
评论