环境:openjdk11,springboot2.3,windows
代码:ExcelUtil.getBigWriter("my.xlsx")
jvm:
Debugger attached successfully.
Server compiler detected.
JVM version is 11+28
using thread-local object allocation.
Garbage-First (G1) GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 2147483648 (2048.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 1287651328 (1228.0MB)
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 1048576 (1.0MB)
Heap Usage:
G1 Heap:
regions = 2048
capacity = 2147483648 (2048.0MB)
used = 105174440 (100.30216217041016MB)
free = 2042309208 (1947.6978378295898MB)
4.897566512227058% used
G1 Young Generation:
Eden Space:
regions = 52
capacity = 1352663040 (1290.0MB)
used = 54525952 (52.0MB)
free = 1298137088 (1238.0MB)
4.0310077519379846% used
Survivor Space:
regions = 0
capacity = 0 (0.0MB)
used = 0 (0.0MB)
free = 0 (0.0MB)
0.0% used
G1 Old Generation:
regions = 53
capacity = 794820608 (758.0MB)
used = 51697064 (49.302162170410156MB)
free = 743123544 (708.6978378295898MB)
6.504243030397118% used
问题:需求是要加载一个大excel进行处理,这个excel有50m,用的是hutool
的excel操作类,但是一执行到这句代码,就会报错。另外好奇一个问题,jvm
的OldSize
为什么默认只有5m?
cn.hutool.poi.exceptions.POIException: IOException: Java heap space
at cn.hutool.poi.excel.WorkbookUtil.createBook(WorkbookUtil.java:86)
at cn.hutool.poi.excel.WorkbookUtil.createSXSSFBook(WorkbookUtil.java:194)
at cn.hutool.poi.excel.WorkbookUtil.createSXSSFBook(WorkbookUtil.java:182)
excel本身是个压缩文件,你把.xlsx后缀的excel用解压软件是可以直接打开的,主要就是一堆XML文件。
所以,看似50M大,因为文本的压缩率很高,实际可能有500M。
500M不小了吧,加上解析excel要创建很多object,那么OOM也就很正常了。解析excel有技巧,不能一次加载全部单元格,具体的代码网上很多了。