资源回收
资源回收
如果有资源需要释放,请在Disposer 中注册
Disposer 主要管理监听器类的资源,也管理以下2种类型的资源
- 文件连接和数据库连接
- 缓存
Disposer 是单例的,由 Disposable 进行管理,Disposable.dispose()方法用于释放资源
The Disposer supports chaining Disposables in parent-child relationships.
自动回收对象
实现了Disposable接口的对象,将会自动回收,例如很重要的使用场景是:
注意:在plugin.xml 注册的扩展 不会自动回收,如果需要回收,需要定义一个服务 ,在它的dispose()方法中释放资源
单例资源回收器
Disposable 以树形的数据结构维护了Disposer,通过以下方法可以注册自己的回收器
Disposer.register(parentDisposable, childDisposable);
选择父类回收器
通过 Disposer.register(parentDisposable, childDisposable)注册回收器的时候,需要指定父类Disposable,父类Disposable和子类Disposable的生命周期是一样的,所以根据对资源生命周期的需求,通过以下方法选择一个合适的父类:
对于贯穿插件整个生命周期的资源,用 应用级或项目级 服务
显示对话框时所需的资源,使用 DialogWrapper.getDisposable().
显示tool windows时所需要的资源,需要调用Content.setDisposer( class implements Disposable )
如果资源的生命周期很短,可以调用 Disposer.newDisposable() 创建Disposable,调用Disposable.dispose()来回收资源,需要注意最好调用Disposer.register(parentDisposable, childDisposable)来指定一个父类回收器,防止调用Disposable.dispose()时出现错误没有释放资源而导致内存泄漏
注意
当卸载插件的时候,用Application 和 Project用作父Disposable的Disposer 的资源不会被回收,会导致内存泄漏,所以Application 和 Project不能用作父Disposable
使用DevKit插件中的 Code -> Incorrect parentDisposable parameter 可以检查是否存在错误
如果不能正确的选择父Disposable,那么这些资源的生命周期可能会延长,导致在每次调用的时候会留下一些多余的僵尸资源,这些问题并不会被内存检查器报告
例如:如果一个UI组件使用了 project-level service 当作父Disposable,那么当UI操作结束后, 这个UI组件会留在内存中,不会被及时回收,导致内存和cpu资源的浪费