热更新框架设计

本文介绍了Java热更新框架的设计思路,包括需求分析、主要类设计和内存泄露测试。通过自定义ClassLoader实现热更新,避免Java Agent的局限性。每个热更新模块对应一个ReloadModule,使用IJarStarter接口定义启动类,FileWatcher监控文件变化。同时,文章强调了内存管理的重要性,以防止内存泄露。
摘要由CSDN通过智能技术生成

热更新框架设计

目前设计只适用于当前系统,且使用框架需要二次开发。

需求简单分析

目前java热更代码的途经有很多,脚本如lua、Python等,Java Agent,自定义ClassLoader,每种方式都各有优缺点:

  1. 各种脚本:脚本语言分两类,基于JVM实现的Groovy、Jython等,这些脚本的热加载实现也是基于自定义ClassLoader;另一种像lua这种纯解释性语言,想要实现热更,只能每次调用都重新load脚本文件执行,或者缓存一份文件,再定义监听器监听文件变化后重新load缓存,实现起来跟自定义ClassLoader类似。
  2. Java Agent:Instrument方式可以直接修改运行时的class结构,但主要用途是修改方法体,不支持修改方法参数、返回值等信息,也不可以随意增删方法;如果是对原有算法进行修改,很难避免对方法返回值、参数等内容的修改,所以该实现方式不做优先考虑
  3. ClassLoader:优点明显,可以全部替换所有代码;缺点也明显,有内存泄露风险,每次热更需要保证之前所有引用都被清除,因为卸载class依赖GC,所以就要求所有自定义ClassLoader加载的class能够在新的classLoader加载完成后,将所有对象实例引用清空,保证原来class没有实例对象。

本次需求是通用热更框架,对于热更内容不确定,更新粒度不确定的内容,目前可以选择的只有ClassLoader。

考虑

  • 使用ClassLoader存在内存泄露风险,所有ClassLoader加载出来的Class和这些Class的实例对象必须统一管理,方便后续更新时统一卸载
  • ~~ClassLoader加载获得是Class,所以获取实例时需要调用class对象的newInstance方法,多少会影响性能,所有需要提供机制保证对象实例复用,~~暂时不考虑性能损耗
  • 热更代码最好不在AppClassLoader中加载,这样可以不用打破双亲委派
  • 安全点,目前设计暂时不考虑安全点,通过tick机制,每帧检测是否存在加载成功的Class实例,存在则直接替换之后再执行正常逻辑

限制

  • 每个tick单元下支持一个热更jar包,如MatchService下可以支持一个热更jar包,利用MatchService的tick驱动ReloadModule去实现热更
  • 热更的代码不可以保留跨Service引用,比如MatchService中热更出来的类不要在其他Service中保存引用
  • 所有需要热更的代码只能存在于单独拉出来的项目中,不能在基础jar包中包含
  • 热更Jar包中必须存在启动类,且需要在MANIFEST.MF文件中配置权限类名

方案

以Jar为单位更新,将需要更新的代码单独划分一个项目,单独打包;Jar包中需要有一个初始化类Starter提供初始化和卸载方法,当需要热更时加载新的Starter并进行初始化,完成替换之后调用之前Starter的卸载方法,删除各种引用。

本次设计没有具体到具体模块,每个需要热更的具体模块都需要在这个设计的基础上进行二次开发,包括IJarStarter实现类、热更代码拆解项目、原项目缓存修改等。

类图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值