使用新线程订阅Observable时,CompositeSubscription会泄漏内存

时间:2017-05-25 17:14:46

标签: android memory-leaks rx-java observable rx-android

在非主线程上订阅Observable并将Observable添加到CompositeSubscriptions时,我们的Android应用程序中存在内存泄漏。这是导致内存泄漏的代码块:

            mSubscriptions.add(Observable.just(imageBytes)
                .subscribeOn(Schedulers.newThread())
                .map(bytes -> {
                    YuvImage yuvimage = new YuvImage(bytes, ImageFormat.NV21, mPreviewWidth, mPreviewHeight, null);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    yuvimage.compressToJpeg(new Rect(0, 0, mPreviewWidth, mPreviewHeight), 100, baos); // Where 100 is the quality of the generated jpeg
                    byte[] jpegArray = baos.toByteArray(); ...
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(result -> {
                    ...
                }, error -> Timber.e(error)));
    }

从不释放map中使用的内存(除非我们调用CompositeSubscriptions.clear())。如果所有内容都在主线程上完成,或者我们没有将Observable添加到CompositeSubscription,则没有内存泄漏。这两种解决方案都不是一种选择。请告知如何以正确的方式执行此操作,以便我们不会耗尽内存。

1 个答案:

答案 0 :(得分:3)

我不确定我是否理解正确但是如果你没有正确管理订阅,你总是可以从应用程序中获得内存泄漏。

所有的拳头 - 你不应该使用<div style="margin-top: 10px"> <button (click)="goToPage(1)" [disabled]="pageNumber==1"> <md-icon>first_page</md-icon> </button> <button (click)="previous()" [disabled]="pageNumber==1"> <md-icon>chevron_left</md-icon> </button> <input #input type="text" style="width: 30px;height:30px;margin-top:2px" (keyup.enter)="goToPage(input.value)" [(value)]="pageNumber" > <button (click)="next()" [disabled]="pageNumber==totalPages"> <md-icon>chevron_right</md-icon> </button> <button (click)="goToPage(totalPages)" [disabled]="pageNumber==totalPages"> <md-icon>last_page</md-icon> </button> <br /> <span>Showing page {{pageNumber}} of {{totalPages}} pages. </span></div> ,因为每次订阅observable时它都会生成新的线程。不应使用Schedulers.newThread(),而应使用newThread()。需要现在可用的线程池。

其次 - 您应该展示如何管理订阅。

Schedulers.io()

如果您需要识别应该取消订阅的订阅,您可以使用简单的onCreate(Bundle saveInstanceState){ subscriptions.add(...); } onPause(){ subscriptions.unsubscribe(); subscriptions.clear(); } 放置

Map<String, Subscription> map