dji-sdk / Mobile-UXSDK-Android

DJI Mobile UXSDK is a suite of product agnostic UI objects that fast tracks the development of Android applications using the DJI Mobile SDK.
Other
152 stars 110 forks source link

PreFlightCheckListPanel内存泄漏希望尽快修复,2个月前就说过,这次把代码找出来,改不改 #107

Closed SJJ-dot closed 3 years ago

SJJ-dot commented 3 years ago

QQ截图20201130170047 QQ截图20201130170516

    private void registerEvent() {
        if (this.isEventRegistered.compareAndSet(false, true)) {
            final Resources var1 = this.getResources();
            if (this.subscriptions == null) {
                this.subscriptions = new CompositeSubscription();
            } else {
                this.unregisterEvent();
                this.subscriptions = new CompositeSubscription();
            }
    private void unregisterEvent() {
        if (this.isEventRegistered.compareAndSet(true, false) && !this.subscriptions.isUnsubscribed()) {
            this.subscriptions.unsubscribe();
            this.subscriptions = null;
        }

    }

看到么,两边条件不一致

dji-dev commented 3 years ago

Agent comment from Luce Luo in Zendesk ticket #41604:

尊敬的用户,

您好!感谢您联系DJI 大疆创新。 抱歉,该问题已经报告给到相关工程师进一步调查处理。

非常感谢您的理解与配合,祝您生活愉快!

Best Regards,

DJI 大疆创新SDK技术支持

lanyusea commented 3 years ago

@SJJ-dot 之前没看过这个代码哈,刚大概看了下片段,感觉条件不一致应该不会产生泄露问题?

注册函数
如果事件没有被注册:
    执行注册。
    检查上一次申请的subscriptions是否还在:
        在的话先释放再申请subscriptions,避免资源泄露
        不在的话直接申请subscriptions
如果事件被注册了:
    什么都不做

释放函数
如果事件没有被注册:
   什么都不做
如果事件被注册了:
    如果subscriptions已经被释放了
        什么都不做
    如果subscriptions没有被释放
        释放

释放函数中多出的对subscriptions是否已经释放的检查:

  1. 如果true,那么确实这部分资源已经在其他地方被释放了,这里不释放也不会造成资源泄露,如果释放了,可能会踩到空指针(?,不是很确定jvm内部的机制,我没有写过java)
  2. 如果false,那么释放掉,资源回收,没有泄露。
SJJ-dot commented 3 years ago

@SJJ-dot 之前没看过这个代码哈,刚大概看了下片段,感觉条件不一致应该不会产生泄露问题?

注册函数
如果事件没有被注册:
    执行注册。
    检查上一次申请的subscriptions是否还在:
        在的话先释放再申请subscriptions,避免资源泄露
        不在的话直接申请subscriptions
如果事件被注册了:
    什么都不做

释放函数
如果事件没有被注册:
   什么都不做
如果事件被注册了:
    如果subscriptions已经被释放了
        什么都不做
    如果subscriptions没有被释放
        释放

释放函数中多出的对subscriptions是否已经释放的检查:

  1. 如果true,那么确实这部分资源已经在其他地方被释放了,这里不释放也不会造成资源泄露,如果释放了,可能会踩到空指针(?,不是很确定jvm内部的机制,我没有写过java)
  2. 如果false,那么释放掉,资源回收,没有泄露。

isEventRegistered在为false的时候再次调用了registerEvent方法,进到里面unregisterEvent导致isEventRegistered为false,下一次再调用unregisterEvent两个条件达不到,至于为什么会达成这样的条件这里确实看不出来,不过这个泄露基本上是必现,我已经通过反射的方式拿到subscriptions解决了这个bug,并且打印了日志看到调用unregisterEvent之前,isEventRegistered确实为false,subscriptions.isUnSub同样为false导致取消条件进不去