SpringBoot Mybatis 数据库流式读取优化(二)

      还是接着上次文章的话题,流式数据库读取和批量数据获取中,方式各有千秋,流式数据读取可以很大的解决内存不足问题,而批量读取可以方便数据一次性收集,编码方便。但是流式真的比批量数据读取占有性能场景下的优势吗?这两天我通过Jconsle分析了下两种场景GC和堆内存的消耗。

流式读取方式:

SpringBoot Mybatis 数据库流式读取优化(二)

从图中可以看出,Old Gen堆区的内存消耗十分严重,

SpringBoot Mybatis 数据库流式读取优化(二)

而程序运行16分钟,GC耗时高达33S,这可以看出流式数据读取采用的策略:时间换空间,减少空间的使用必然带来大量的OldGen的消耗,在高性能程序处理上,这样带来容忍度是相当不行。

批量读取数据:

SpringBoot Mybatis 数据库流式读取优化(二)

呵呵,详细大家可能能猜出大概的结果,60W条数据一次读取到内心中,大概消耗200M左右。OldGen占比不高,但是Survor 区域内存占比比较高。这种场景下下触发FullGC场景不多,Minor GC基本完成了内存的释放工作。

SpringBoot Mybatis 数据库流式读取优化(二)

GC消耗不过3S,同样运行15分钟。可以看出触发FulGC的时间非常小,空间换时间带来的增益必然是GC时间更小,更快的体验。

   

总结:

       均衡程序的性能必然是在时间和空间两个角度考虑,在程序空间不足情况下,流式数据读取可以带来空间增益。而Old Gen GC体验带来的往往是卡顿和CPU占用过高。于此对比的批量方式是消耗更多的内存,但是带来是流畅的运行和少一些FulGC的感觉。至于使用何种方式,可能更需要从实际的业务角度出发。