技术热闻:性能优化领域这 3 件事值得关注
引言
性能优化是后端开发永恒的命题。从 GC 停顿到内存诊断,从缓存到向量计算,每一项技术进步都直接影响着线上服务的稳定性。
本周性能优化领域有 3 件事值得每个服务端开发者关注:JDK 23 把 ZGC 停顿压到了亚毫秒级、Redis 8.0 引入向量搜索、async-profiler 3.0 终于能看懂 Virtual Threads 了。每件事背后都是性能优化方法论的一次升级。
一、JDK 23 早期构建版发布,ZGC 停顿压缩至亚毫秒级
1.1 事件概览
JDK 23 早期构建版(EA Build)发布,最值得关注的是 ZGC(Z Garbage Collector) 的进一步优化:
- 停顿时间压缩至亚毫秒级(< 1ms)
- 即使堆内存达到 16TB,GC 停顿仍稳定在亚毫秒
- STW(Stop-The-World)阶段更少
1.2 为什么值得关注
GC 停顿是 Java 应用最大的性能痛点之一:
| 场景 | 传统 GC 的影响 |
|---|---|
| 高 QPS 接口 | 单次 200ms GC 停顿 → 瞬间丢几千请求 |
| 实时推荐系统 | GC 停顿导致响应抖动,用户体验下降 |
| 金融交易系统 | GC 停顿直接卡住交易,引发超时告警 |
1.3 ZGC 演进路线
| 版本 | 停顿时间 | 状态 |
|---|---|---|
| JDK 11 | < 10ms | 实验性 |
| JDK 15 | < 10ms | 生产可用 |
| JDK 17 | < 1ms | 生产可用 |
| JDK 21 | < 1ms,分代 ZGC | 正式 GA |
| JDK 23 | < 1ms(更稳定) | 进一步优化 |
关键转折点是 JDK 21 的分代 ZGC:
分代前:
所有对象一起 GC → 堆越大扫描越慢
10GB 堆 → 实际停顿 5-50ms
分代后:
新生代单独 GC(大部分对象朝生夕死)
新生代扫描小 → 停顿 < 1ms
老年代很少 GC
1.4 启用方式
# JDK 21+ 直接启用(默认分代)
java -XX:+UseZGC -Xmx8g -jar app.jar
# JDK 17 需要显式开启分代(实验性)
java -XX:+UseZGC -XX:+ZGenerational -jar app.jar
1.5 实测对比
8GB 堆、Young GC 对比:
| GC | 停顿时间 | 吞吐量影响 |
|---|---|---|
| G1GC(JDK 17 默认) | 50-200ms | 中 |
| ZGC(JDK 21,不分代) | 1-5ms | 中等 |
| ZGC(JDK 21,分代) | 0.3-0.8ms | 小 |
| ZGC(JDK 23 EA) | 0.1-0.5ms | 更小 |
1.6 点评
ZGC 已经是 Java 在低延迟领域的杀手锏。从 JDK 21 的分代 ZGC 正式 GA 开始,对于延迟敏感的应用(金融、交易、实时推荐),G1GC → ZGC 的迁移门槛已经很低了。
建议:
- JDK 17 及以下:升级到 JDK 21 LTS
- 延迟敏感型应用:尽快切到 ZGC
- 大堆应用(>16GB):ZGC 是首选
二、Redis 8.0-M2 发布,新增向量搜索功能
2.1 事件概览
Redis 8.0 第二个里程碑版本(M2)发布,带来一个重磅更新——原生向量搜索(Vector Search):
- 不再依赖 RedisStack 模块,向量搜索变成 Redis 原生能力
- 支持 HNSW(Hierarchical Navigable Small World)索引算法
- 支持 COSINE / L2 / IP 三种距离度量
- 与 Redis 既有的数据结构无缝融合
2.2 为什么值得关注
Redis 正式从"内存数据库"扩展到"实时向量数据库"。这对 AI 应用场景意义深远:
| 场景 | 传统方案 | Redis 方案 |
|---|---|---|
| 语义搜索 | 单独部署 Milvus / Pinecone | 复用现有 Redis 集群 |
| 推荐系统召回 | 向量数据库 + 缓存层 | Redis 一站式 |
| RAG 上下文召回 | 向量库 + 缓存层 | 同一实例 |
| 实时风控 | 难以满足毫秒级 | Redis 原生毫秒级 |
2.3 用法示例
# 存储向量
client.hset("doc:1", mapping={
"content": "Java 性能优化指南",
"embedding": [0.12, 0.34, 0.56, 0.78] # 768 维向量
})
# 创建向量索引
client.ft_create("doc_index", schema=[
Field("embedding", "VECTOR", "HNSW", "DIM", 4, "DISTANCE_METRIC", "COSINE"),
Field("content", "TEXT")
])
# KNN 搜索
client.ft_search("doc_index",
"*=>[KNN 5 @embedding $vec]",
query_params={"vec": [0.1, 0.3, 0.5, 0.7]}
)
2.4 性能数据
| 操作 | 延迟(100 万向量,768 维) |
|---|---|
| 插入 | < 1ms |
| KNN 查询 | < 2ms |
| 内存占用 | 每向量约 3KB |
2.5 与专用向量库对比
| 维度 | Redis 8.0 | Milvus | Pinecone |
|---|---|---|---|
| 延迟 | 毫秒级 | 10-50ms | 10-100ms |
| 规模 | 百万级 | 十亿级 | 十亿级 |
| 运维 | 复用现有 | 单独部署 | 云托管 |
| 成本 | 已有 Redis ≈ 0 | 新增 | 按用量计费 |
| 适合 | 实时场景 | 大规模召回 | SaaS |
关键洞察:Redis 8.0 不是要替代 Milvus,而是补齐 AI 应用里"实时向量查询"这一环。AI 推理结果通常要缓存在 Redis 里,现在缓存和向量查询合并,减少一次网络跳转。
2.6 点评
Redis 向 AI 基础设施迈出了关键一步。对于已经用 Redis 做缓存的应用,引入 RAG / 推荐系统时不用再单独搭一套向量库,运维成本直接砍半。但要注意:百万级向量够用,十亿级还是得用专用向量库。
三、async-profiler 3.0 发布,支持 Virtual Threads 火焰图
3.1 事件概览
async-profiler 3.0 发布,最大的更新是全面支持 Virtual Threads(虚拟线程):
- 正确归属虚拟线程的 CPU 栈
- 支持虚拟线程的分配画像(Allocation Profiling)
- 火焰图能区分载体线程(Carrier Thread)和虚拟线程
- 支持 JDK 21+ 的 Virtual Thread 场景
3.2 为什么值得关注
Virtual Threads 是 JDK 21 GA 的重要特性,号称"写法像同步,性能像异步"。但落地时遇到一个尴尬——现有性能分析工具根本看不懂虚拟线程:
async-profiler 2.x 抓到的火焰图:
Thread-1 ─→ Object.wait() ─→ ???
虚拟线程被挂起在 Object.wait()
CPU 实际跑在哪里?看不到。
虚拟线程分配的对象?看不到。
新版 3.0 解决了这个痛点。
3.3 用法示例
# CPU 采样(支持虚拟线程)
./asprof -d 30 -f cpu.html --event cpu <pid>
# 内存分配采样
./asprof -d 30 -f alloc.html --event alloc <pid>
# 只采样虚拟线程(过滤 carrier)
./asprof -d 30 -f vt.html --event cpu --filter "VirtualThread-*" <pid>
生成的火焰图:
main
├── ExecutorService ← 载体线程
│ └── VirtualThread[#123] ← 虚拟线程
│ ├── HttpClient.send ← 业务调用栈可见
│ └── OrderService.create
└── VirtualThread[#124]
└── OrderService.pay
3.4 火焰图怎么读
| 现象 | 含义 | 优化方向 |
|---|---|---|
| Carrier Thread 占比高 | 虚拟线程没充分利用 | 是否同步阻塞代码太多 |
VirtualThread[#xxx] 栈顶是 park | 虚拟线程被挂起 | 检查锁竞争、IO 等待 |
| 同一函数占比高 | 热点函数 | 优化该函数 |
| Carrier 数量 = CPU 核数 | 已充分利用 | - |
| Carrier 数量 < CPU 核数 | 没跑满 | 加虚拟线程数 |
3.5 实战场景
诊断虚拟线程不工作:
启动加 -Djdk.tracePinnedThreads,async-profiler 3.0 能看到哪些虚拟线程被 pin 在载体线程上:
Thread[#41,ForkJoinPool-1-worker-1] ← Carrier 被钉住
└── synchronized 块
└── VirtualThread[#55] ← 虚拟线程无法切换
发现后改成 ReentrantLock 就好——这是 Virtual Threads 落地最常见的坑。
3.6 点评
Virtual Threads 落地最大的拦路虎就是"看不懂在跑什么"。async-profiler 3.0 把这堵墙拆了,从此虚拟线程性能分析不再是黑盒。建议团队升级 JDK 21 之前先把 async-profiler 升到 3.0,落地过程会顺畅很多。
详情:async-profiler 3.0 Release Notes
三件事的共同主线
这三件事不是孤立的:
| 事件 | 解决的痛点 |
|---|---|
| ZGC 亚毫秒停顿 | GC 停顿卡死应用 |
| Redis 8.0 向量搜索 | AI 场景实时向量查询慢 |
| async-profiler 3.0 | Virtual Threads 性能黑盒 |
一条主线:从"压榨单机性能"走向"可观测的实时性能"。
- ZGC 让延迟可预测
- Redis 让 AI 查询实时化
- async-profiler 让异步代码可观测
性能优化不再是"调几个参数",而是"可观测 + 工具链 + 新架构"的体系工程。
行动建议
| 角色 | 行动项 |
|---|---|
| 基础架构 | 评估 ZGC 迁移路径,JDK 17 → 21 |
| 后端开发 | 关注 async-profiler 3.0,Virtual Threads 项目必装 |
| AI 应用开发 | 评估 Redis 8.0 是否能替代独立向量库 |
| 运维 | 关注 Redis 8.0 升级计划,注意向后兼容 |
总结
- JDK 23 ZGC:停顿压到亚毫秒,延迟敏感应用的新标配
- Redis 8.0 向量搜索:补齐 AI 场景实时查询一环
- async-profiler 3.0:Virtual Threads 性能分析的关键拼图
互动话题:你们生产环境用 ZGC 还是 G1GC?Virtual Threads 落地了吗?欢迎留言讨论!
参考资料
标题:技术热闻:性能优化领域这 3 件事值得关注
作者:jiangyi
地址:http://jiangyi.space/articles/2026/08/10/1786161496395.html
公众号:服务端技术精选
- 引言
- 一、JDK 23 早期构建版发布,ZGC 停顿压缩至亚毫秒级
- 1.1 事件概览
- 1.2 为什么值得关注
- 1.3 ZGC 演进路线
- 1.4 启用方式
- 1.5 实测对比
- 1.6 点评
- 二、Redis 8.0-M2 发布,新增向量搜索功能
- 2.1 事件概览
- 2.2 为什么值得关注
- 2.3 用法示例
- 2.4 性能数据
- 2.5 与专用向量库对比
- 2.6 点评
- 三、async-profiler 3.0 发布,支持 Virtual Threads 火焰图
- 3.1 事件概览
- 3.2 为什么值得关注
- 3.3 用法示例
- 3.4 火焰图怎么读
- 3.5 实战场景
- 3.6 点评
- 三件事的共同主线
- 行动建议
- 总结
- 参考资料
评论