Java 中 ArrayList 扩容机制怎么排查由于未预估容量导致的性能抖动

秋敏小哥_4044

秋敏小哥_4044

2026-10-01

909人浏览

原创

定位arraylist频繁扩容引发性能抖动,需结合gc日志高频allocation failure、jfr中grow/copyof分配事件突增、async-profiler中arrays.copyof cpu占比超5%等运行时指标;高风险场景包括循环内新建空列表、批量添加未预设容量、无效ensurecapacity调用;arthas可动态watch grow行为验证扩容模式;优化后应观察p99/p999响应毛刺消失及gc暂停波动收窄。

java 中 arraylist 扩容机制怎么排查由于未预估容量导致的性能抖动

排查 ArrayList 因未预估容量引发的性能抖动,核心是定位“频繁扩容”这一行为本身——它会触发大量 Arrays.copyOf 调用,造成 CPU 突增、GC 压力升高、响应延迟波动。关键不在于看代码有没有 new ArrayList(),而在于观察运行时是否发生了密集、小步长的数组复制。

从 JVM 运行时指标入手抓异常扩容

扩容本质是内存分配 + 数组拷贝,会在以下维度留下明显痕迹:

  • GC 日志中出现高频的“Allocation Failure”和短生命周期大对象:每次扩容都新建一个更大的数组(如从 10→15→22→33…),若初始为空且快速添加数百元素,会生成多个中等大小(KB 级)的 Object[],被 G1 或 ZGC 快速回收,日志中表现为密集的 Young GC;
  • JFR(Java Flight Recorder)中 jdk.ObjectAllocationInNewTLAB 事件突增,且分配栈深度浅、集中在 ArrayList.grow 或 Arrays.copyOf:开启 JFR 录制 60 秒,筛选 allocation 事件,按 stack trace 分组,若 top 几名全是 grow() → copyOf() → add(),基本可确认;
  • 线程 CPU 样本中 Arrays.copyOf 占比异常高(>5%):用 async-profiler 采样 CPU,火焰图里若该方法频繁出现在 add 调用链底部,说明扩容已成为热点。

通过代码静态扫描识别高风险点

不是所有 new ArrayList() 都有问题,但以下模式大概率导致抖动:

javascript-pro
javascript-pro

专注现代 ECMAScript、异步编程、性能优化和全栈的 JavaScript 专家,适用于现代开发

下载
  • 循环内反复创建空 ArrayList:例如在 for 循环或 stream map 中写 list.add(...); return new ArrayList(list),每次调用都从 0 开始扩容;
  • 批量构建场景未指定容量:如 DAO 层查出 5000 条记录后 new ArrayList() 再逐条 add,实际会扩容约 12 次(10→15→22→33→49→73→109→163→244→366→549→823→1234→1851→2776→4164);
  • 构造后立即调用 ensureCapacity(0) 或无效预估:比如预估为 1,但实际加 1000 个元素,毫无作用。

用 Arthas 动态观测正在发生的扩容

无需重启,直接在线验证某次请求是否触发了非预期扩容:

  • 执行 watch java.util.ArrayList grow '{params,returnObj}' -n 5,观察每次扩容前的 minCapacity 和计算出的 newCapacity;若发现连续几次 minCapacity=11,12,13... 且 newCapacity 每次只微增(如 15→15→15→22),说明是“边加边扩”的低效模式;
  • 配合 trace java.util.ArrayList add 查看单次请求中 add 被调用了多少次、耗时分布,若末尾几次 add 耗时陡增(因触发 grow),就是扩容抖动的直接证据。

验证优化效果的简单压测法

改完代码后,不要只看平均 RT,重点看 P99/P999 的毛刺:

  • 用 JMeter 或 wrk 对同一接口施加稳定 QPS(如 100/s),持续 2 分钟;
  • 对比优化前后 响应时间直方图:未优化时,常有少量请求耗时突然跳到 50–200ms(扩容拷贝阻塞线程);优化后,99% 请求应落在窄带宽内(如 2–8ms);
  • 同时监控 JVM 的 gc.pause 和 thread.count,抖动消失后,这两项的峰值波动幅度应显著收窄。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

9417

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

6582

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

5852

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1024

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

868

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1236

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2469

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

19811

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1115

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习