核心是分层协同控制数据缓存位置、容量与刷新时机:MySQL需useCursorFetch=true+setFetchSize(Integer.MIN_VALUE),PostgreSQL设setFetchSize(500),每500–1000行显式flush,BufferedWriter缓冲建议8KB–64KB,务必及时close。

核心是控制“数据在哪缓、缓多少、何时刷”,不是只盯着 BufferedWriter 或 PreparedStatement 的缓冲区大小,而是分层管理:数据库端拉取、JDBC 驱动中转、Java 层写入三段协同。
分批读取 ResultSet,避免全量加载到 JVM
内存暴涨主因常是 JDBC 一次把几百万行全拖进内存。必须启用流式或分页拉取:
-
MySQL:URL 加
?useCursorFetch=true,执行前调用statement.setFetchSize(Integer.MIN_VALUE) -
PostgreSQL:默认支持流式,设
setFetchSize(500)即可(100–2000 区间较稳) -
Oracle:配合
setFetchSize(1000)和setRowPrefetch(1000) - 通用兜底:用
LIMIT/OFFSET或游标分页(如WHERE id > ? ORDER BY id LIMIT 1000),每次只查一批
写入阶段主动 flush,不依赖 close
BufferedWriter 默认 8KB 缓冲,它不按“行”缓存,只缓字符数组;真正积压的是你写入的内容没及时落盘:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 每写入 500–1000 行后显式调用
writer.flush(),释放底层 char[] - 不要在循环里只写不刷,尤其当目标是慢速设备(如 NFS、远程挂载盘)时
-
close()会自动 flush,但只应在最后调用;中途不 flush 可能导致 OOM - 若复用同一个
BufferedWriter写多批次,确保前一批已flush(),再写下一批
合理设置缓冲区与连接生命周期
缓冲区不是越大越好,要匹配实际吞吐和 GC 压力:
- 默认 8KB 足够日常使用;高吞吐场景可设为 32KB 或 64KB:
new BufferedWriter(new FileWriter(file), 64 * 1024) - 缓冲区超过 1MB 易增加 GC 压力,不建议盲目调大
- 务必用
try-with-resources或finally确保close(),防止资源泄漏导致缓冲未释放 -
ResultSet和Statement用完立刻close(),释放 JDBC 驱动内部缓冲
配套 JVM 与编码优化
辅助降低整体内存水位:
- 拼接写入内容优先用
StringBuilder,避免字符串加法产生大量临时对象 - JVM 启动参数加
-XX:+UseG1GC,堆内存建议设为-Xmx2g起步,避免频繁 Full GC - 考虑用
Files.newBufferedWriter()(NIO.2)替代传统FileWriter + BufferedWriter,更轻量且支持追加
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










