背景
- 在interface EnhanceBaseMapper extend BaseMapper中存在一个自定义的defaul方法,该方法将传入的List数据按照大小 分片List<List>。然后调用insertBatchSomeColumn方法
- 此业务场景的QPS为几十
问题
- 发现只要走了该方法,JVM的GC时间会变长。
- GC时间从0.03ms增大到几十ms
解决方案
- 将该方法单独提出来,利用statistic修饰,单独放到工具类中,方法内部逻辑不变。则避免了GC过长问题
原因
- 可能是由于mapper的interface下创建的抽象类方法会随着代理类频繁变化,但是可能default方法为了防止多继承造成的问题,应该是把该方法定义在全局上的。而随着运行的时间越来越长,该方法中的对象会越来越多,因此思考将该方法提出interface。减少对象的创建频率。
- 变长和频繁不一样,频繁可能是一次GC间隔创建太多的对象,变长可能是对象没有释放
- 在 MyBatis 的 Mapper 接口中定义的方法属于动态生成的代理类,这些代理类由 MyBatis 的 Mapper 接口和相应的 XML 文件动态生成。这些代理类是在运行时通过反射和动态代理生成的,它们的生命周期通常与应用程序的生命周期一致。因此,如果在 MyBatis 的 Mapper 接口中定义了一个 default 方法,这个方法会被添加到代理类中,并且会在应用程序的生命周期内一直存在于内存中。
- 当你将这个方法移到一个工具类中并使用 static 修饰时,这个方法不再属于 MyBatis 的 Mapper 接口的代理类,而是属于工具类的静态方法。静态方法是在类加载时就加载到内存中的,并且在整个应用程序的生命周期内一直存在于内存中。因此,将方法移到工具类中并使用 static 修饰后,该方法的生命周期与应用程序的生命周期一致,而不会受到代理类的动态生成和销毁的影响。