日期:2026-07-12
标签:#面试 #八股 #后端 #数据同步 #OOM #线上问题排查
一句话答案
先确认 OOM 类型和内存增长对象,常见根因是全量加载、批次/队列无界、状态无限增长或 Sink 变慢;通过流式读取、有界缓冲、批次调优、背压、状态 TTL 和资源隔离解决。
面试口语版
先看异常是 Java heap、direct memory、GC overhead 还是容器 OOMKilled,保留 heap dump、GC 日志、线程栈和同步指标。MAT 看 Retained Size 和引用链,结合队列长度、批次、反序列化对象、维表缓存、Flink state 和下游延迟判断。常见错误是一次把全表/ResultSet 放 List、fetchSize 无效、队列无界、批量提交前长期积累、失败重试对象不释放。修复为数据库流式游标、固定批次、边读边写、有界队列和背压;大状态放 RocksDB/外部存储并设 TTL,批次提交后及时清引用。
关键细节
- 增大堆只能缓解,若输入长期大于输出仍会再次 OOM。
- JDBC 流式读取配置依驱动版本,必须实测。
- 直接内存 OOM 要查 Netty/压缩缓冲,不只看 Heap Dump。
- 限制单条异常大消息和反序列化大小。
面试官追问
- 如何判断是队列积压导致 OOM?
- 批次越大性能越好吗?
- 增大 JVM 堆是否能解决?
面试官追问参考答案
1. 如何判断是队列积压导致 OOM?
内存曲线与队列长度、消费 Lag 同步增长,Heap Dump 中大量消息对象由队列节点持有,下游吞吐低于上游。限制队列后若出现背压而内存稳定,证据更明确。
2. 批次越大性能越好吗?
批量能摊薄网络和事务开销,但过大会增加内存、延迟、锁、失败重试成本和请求大小。应在吞吐、P99、内存和下游限制之间压测选择,并设置按条数与字节双重上限。
3. 增大 JVM 堆是否能解决?
只有工作集合理但暂时空间不足时有效;无界队列、泄漏或输出不足时只是延迟故障,还可能增加 GC 停顿。应先修复内存模型和背压,再按容量调整堆。
学习清单
- 能按 OOM 类型收集证据。
- 掌握流式、有界、背压和状态 TTL。