訂閱非主線程上的Observable並將該Observable添加到CompositeSubscriptions時,我們的Android應用程序中存在內存泄漏。這是代碼導致內存泄漏的塊:CompositeSubscription在使用新線程訂閱Observable時泄漏內存
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)));
}
內部地圖中使用的存儲器是永遠不會被釋放(除非我們稱之爲CompositeSubscriptions.clear())。如果一切都在主線程上完成,或者如果我們不將Observable添加到我們的CompositeSubscription,則沒有內存泄漏。這兩種解決方案都不是一種選擇。請告知如何以適當的方式做到這一點,所以我們不會耗盡內存。
感謝您的答覆。我們使用調度程序,newThread僅僅是一個例子。無論我們使用自己的調度程序,rx庫還是新線程提供的調度程序都會發生內存泄漏。我們正在根據生命週期清理複合訂閱,這是行得通的。上面的塊稱爲每秒幾次,它處理圖像,因此消耗大量內存。它沒有任何生命週期事件泄漏,所以它沒有關係。快速修復將清除onCompleted中的這個可觀察對象的每個訂閱,但這不能解決根本原因。 – njosa
我想知道爲什麼內存不會被GC釋放,當我們在非主線程上執行此操作時,它在主線程上執行時完美工作。 – njosa
'onCompleted'事件是有風險的,因爲你不能確定這個事件會被永遠調用。 –