← 每日面试题 学习看板

什么是POI,为什么它会导致内存溢出?

面试题/01实践场景题/实践场景题目/Java生态与编程/什么是POI,为什么它会导致内存溢出?.md

面试记录 2026-10-14

题目:什么是 POI,为什么它会导致内存溢出?

难度:low

标签:practice/java, jvm/memory

评分:⭐⭐⭐☆☆(3/5)

我的回答

POI 是用来进行 excel 等表格解析的工具,内存中要加载 excel 等表格的内容,如果使用全量加载,单次加载过大的 excel 表格,就有可能导致内存溢出;

处理上可以使用流式加载,分批次的进行读取加载,而不是一次性全部读取,防止内存溢出

点评

优点:

不足:

补充:

完整讲解

第一部分:知识重点剖析

核心考点定位:考察对 Java IO 生态中"内存模型选择"的理解——不是"POI 会 OOM",而是"什么时候会、怎么避免"。

知识点拆解:

  1. POI 的四种实现:
  1. 内存放大系数:xlsx 是 zip 格式,解压后 DOM 加载通常放大 5-10 倍;100MB xlsx → 500MB-1GB heap
  2. 典型 OOM 场景:读百万行 xlsx 全量加载、并发多个 workbook 未 close、SXSSF 忘调 dispose() 临时文件堆积
  3. 替代方案对比:
  1. 工程实践:限制并发读 xlsx 的线程数、用对象池复用 Workbook、监控 -XX:+HeapDumpOnOutOfMemoryError

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. XSSF 和 HSSF 的内存差异具体有多大?给个数字。
  1. EasyExcel 为什么能保持内存恒定?
  1. 线上跑了一个读 500MB xlsx 的任务,OOM 了,怎么事后复盘?

第三部分:面试者参考回答(三步法口语化,300-400 字)

【一句话结论】

面试官您好,POI 是 Apache 的 Excel 解析库,OOM 的根因是它默认用 DOM 模型全量加载到内存——xlsx 是 zip 压缩,解压后 DOM 通常放大 5-10 倍,100MB 文件能吃掉 1GB heap。

【三点展开】

第一,POI 有四个实现要分清楚:HSSF(.xls DOM)、XSSF(.xlsx DOM)、SXSSF(.xlsx 流式写,滑动窗口)、SAX API(.xlsx 流式读,事件驱动)。读大文件必须用 SAX,写大文件用 SXSSF,DOM 只适合小文件。

第二,内存放大是核心坑:xlsx 是 zip 格式,解压后每个 cell 在内存里是完整对象,100MB xlsx 解压后可能 1GB heap。典型 OOM 堆栈是 OutOfMemoryError: Java heap space + 大量 Row/Cell 占 Old 区。SXSSF 默认保留 100 行,超过自动刷到临时文件,用完必须调 dispose() 释放临时文件。

第三,生产上替代方案首选 EasyExcel——阿里基于 SAX 封装,1 万行内存恒定 < 10MB,API 用 @ExcelProperty 注解映射,比手写 SAX 回调简洁得多。配合堆监控 + HeapDumpOnOutOfMemoryError 抓 dump 分析 retained heap,能快速定位是不是 DOM 加载惹的祸。

【一句边界】

当然,如果是几十行的小文件做模板填充,XSSF 直接用完全没问题,不必为了流式而流式——SXSSF/EasyExcel 的 API 更啰嗦,小场景反而降低可读性。