开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
使用shardingjdbc版本为3.0.0
由于系统出现GC较多,于是导出dump内容进行分析。可以看出ParsingResultCache类的对象占用内存较高。
如下图源码shardingjdbc使用WeakHashMap进行缓存的存储,这样可以保证不用手动释放引用且保证内存不被过度使用,因为弱引用对象只能存活到下一次 GC 之前。
java四大引用:强引用、软引用、弱引用、虚引用
强引用:一般把一个对象赋值给一个变量。在垃圾回收器不会回收该对象,当内存不足时会抛出OOM异常。
软引用:在内存足够时垃圾回收器不会回收,但内存不足时会回收这些对象。
弱引用:在每次GC时,该部分都会被垃圾回器回收。
虚引用:虚引用在任何时候都有可能会被垃圾回收器回收。
其中WeakHashMap缓存的 key就是预编译的sql语句,在java中预编译使用“?”占位符。例如:
INSERT INTO t1 (c1, c2, c3, c4, c5) VALUES
--下面value动态拼接,可能是任意多条,这样会在WeakHashMap中产生大量缓存数据。
(?, ?, ?, ?, ?),
(?, ?, ?, ?, ?);
当使用批量插入时,由于插入数据的条数不固定,则拼接的sql的语句不定长,这样导致WeakHashMap中缓存大量类似的sql(只是拼接的插入条数不同)。且由于程序是批量循环执行,导致每次GC之间WeakHashMap缓存大量数据。
结论:
在使用shardingjdbc时,尽量避免大量的不同长度的sql循环执行。尤其是使用批量插入时,动态凭借的数据条数尽量固定。避免内存占用过高,GC次数增加。