Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

    • Java IO概述
    • IO基础

    • 常用IO流

    • 文件与目录操作

    • Java NIO

    • 高级主题

    • 实践与性能优化

      • try-with-resources资源管理
      • 大文件读写
      • 文本文件处理
      • IO性能优化
        • 1. 先定位瓶颈
        • 2. 使用缓冲
        • 3. 避免一次性加载
        • 4. 减少不必要的转换
        • 5. 使用 FileChannel 和零拷贝
        • 6. 使用内存映射
        • 7. 线程模型优化
        • 8. 批量和合并
        • 专家实践清单
        • Tips 快问快答
        • 9. 总结
      • IO常见坑
    • 面试与设计题

    • IO实践速查

  • JVM

目录

IO性能优化

IO 性能优化不能只看 Java 代码。真正的瓶颈可能在磁盘、网络、文件系统、操作系统页缓存、线程模型、序列化、业务处理或下游服务。

# 1. 先定位瓶颈

优化前先回答几个问题:

  • 是读慢还是写慢?
  • 是磁盘慢还是网络慢?
  • 是 IO 慢还是业务处理慢?
  • 是吞吐不足还是延迟过高?
  • 是单请求慢还是并发下慢?
  • GC 是否影响 IO 缓冲和吞吐?

没有测量就优化,很容易把代码写复杂却没有收益。

# 2. 使用缓冲

最常见优化是减少小块 IO。

try (InputStream input = new BufferedInputStream(Files.newInputStream(source));
     OutputStream output = new BufferedOutputStream(Files.newOutputStream(target))) {

    byte[] buffer = new byte[64 * 1024];
    int len;
    while ((len = input.read(buffer)) != -1) {
        output.write(buffer, 0, len);
    }
}

缓冲区不是越大越好,要结合压测。

# 3. 避免一次性加载

大文件不要使用:

Files.readAllBytes(path);
Files.readAllLines(path);

改为流式处理:

try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) {
    lines.forEach(this::process);
}

# 4. 减少不必要的转换

频繁在 byte[]、String、对象之间转换会增加 CPU 和内存压力。

例如网络代理只是转发二进制数据,就不应该转换成字符串。

byte[] -> String -> byte[]

这不仅慢,还可能因为字符集导致数据损坏。

# 5. 使用 FileChannel 和零拷贝

大文件复制或发送可以考虑:

fileChannel.transferTo(position, count, targetChannel);

适合数据搬运,不适合需要逐字节业务处理的场景。

# 6. 使用内存映射

大文件随机访问可以考虑 MappedByteBuffer。

适合:

  • 大文件索引。
  • 固定格式数据。
  • 高频随机读。

要注意:

  • 映射释放。
  • 直接内存。
  • 文件锁和跨平台行为。
  • 崩溃一致性。

# 7. 线程模型优化

IO 密集任务可以适当增加线程数,但不是越多越好。

问题包括:

  • 线程太少:IO 等待期间 CPU 利用不充分。
  • 线程太多:上下文切换和内存占用增加。
  • 磁盘或下游已经饱和:增加线程只会排队更严重。

网络高并发场景应考虑 NIO 或成熟框架。

# 8. 批量和合并

频繁小写入可以合并:

  • 批量写日志。
  • 批量刷盘。
  • 批量网络发送。
  • 使用缓冲队列削峰。

但批量会增加延迟和丢失窗口,需要在吞吐和可靠性之间权衡。

# 专家实践清单

优化方向 先看指标 可能手段
减少系统调用 调用频率、吞吐 缓冲、批量
降低内存压力 GC、分配速率 复用缓冲、流式处理
减少复制 CPU、上下文切换 零拷贝、mmap
避免阻塞扩散 线程状态、队列 线程池隔离、超时
提升可靠性 错误率、重试量 限流、幂等、临时文件

优化顺序:

测量瓶颈
  ▼
消除明显错误
  ▼
调整缓冲和批量
  ▼
隔离线程和下游
  ▼
评估高级 IO 技术

# Tips 快问快答

Q:IO 优化第一步是什么? A:测量瓶颈,确认慢在磁盘、网络、CPU、内存、锁还是下游。

Q:为什么缓冲能提升性能? A:减少系统调用和小块读写次数。

Q:为什么批量能提升吞吐? A:摊薄固定开销,但会增加延迟和失败窗口。

Q:零拷贝适合所有 IO 吗? A:不适合,只适合数据搬运类场景。

Q:IO 线程池为什么要隔离? A:慢 IO 会占满线程,拖垮其他业务。

Q:大 byte[] 分配有什么风险? A:增加 GC 压力,甚至导致内存碎片或 OOM。

Q:优化后怎么证明有效? A:对比吞吐、P95/P99、CPU、GC、队列长度和错误率。

Q:高级优化最大风险是什么? A:复杂度提升但收益不明显,且故障排查更难。

# 9. 总结

IO 性能优化的顺序应是:测量瓶颈、减少小 IO、避免一次性加载、减少不必要转换、选择合适模型、再考虑零拷贝和内存映射。越高级的技术,越需要明确收益和维护成本。

上次更新: 2026/06/25, 14:19:18
文本文件处理
IO常见坑

← 文本文件处理 IO常见坑→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式