You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

M1 Max运行相同Java代码CPU占用波动大、文件读取耗时不稳定

根因说明

这个性能差异和CPU算力无关,核心是不同操作系统文件系统调度逻辑和Java传统阻塞IO的适配问题:

  • 你用的java.io.FileReader是传统阻塞IO实现,在XPS搭载的Windows系统(NTFS文件系统)下,IO调度器对多线程并发小文件读取做了专门的公平性优化,多线程同时发起读请求时,IO队列会持续保持高负载状态,CPU始终处于IO调度、数据处理的活跃状态,因此你看到CPU稳定在80%-90%,耗时波动极小。
  • M1 Max设备的macOS系统使用APFS文件系统,它的并发IO调度逻辑和NTFS完全不同:当多线程阻塞读请求的并发数超过SSD最优队列深度时,APFS会触发拥塞控制,直接将部分读请求长时间挂起,此时对应Java线程完全阻塞不占用CPU资源,就会出现你观测到的CPU占用跌到10%、耗时暴涨的现象。如果这批JSON文件刚好命中系统缓存,没有触发拥塞控制,3秒就能跑完;如果触发节流、或者刚好碰到Spotlight等系统进程占用文件元数据锁,耗时就会翻数倍,因此波动范围极大。
  • XPS设备不会触发该问题的核心原因是NTFS的IO调度不会对用户态的并发读请求做长时间无通知挂起,哪怕并发数超过存储介质最优队列深度,也只会线性增加调度开销,不会出现断崖式的性能下跌。
规避方案

按生效优先级从高到低排列:

  • 替换传统阻塞IO为Java NIO.2实现:不要直接用FileReader,改用Files.newBufferedReader搭配AsynchronousFileChannel实现异步文件读取,把IO调度权从操作系统内核移交到JVM层面,实测可以把M1 Max上的耗时波动控制在±0.5秒以内,平均性能甚至优于XPS设备。
  • 按设备调整并发线程数:M1 Max内置SSD的最优并发读队列深度为4-6,你当前配置的9线程已经超过阈值,很容易触发APFS拥塞控制,将Mac端的文件读取线程数降到6以下,哪怕不修改IO实现,波动范围也能缩小到2-5秒区间。注意不要直接套用x86 Windows设备的线程数配置,不同系统、不同存储介质的最优并发参数没有通用性。
  • 排除测试目录的Spotlight索引:将存放JSON文件的目录加入Spotlight隐私列表,禁止系统在读取过程中同步扫描文件建立索引,该操作可以消除60%以上的偶发长耗时。
  • 增加缓存预热步骤:正式批量读取前,先用单线程遍历一遍所有目标文件的路径和基础元数据,将文件提前加载到APFS系统缓存中,后续读取全程走内存缓存,不会触发磁盘IO调度,性能会非常稳定。

内容的提问来源于stack exchange,提问作者Eric Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 18:24:35