skydoves / ColorPickerPreference

🎨 A library that lets you implement ColorPicker, ColorPickerDialog, ColorPickerPreference.
Apache License 2.0
480 stars 51 forks source link

memory leak ColorPickerPreference #27

Open dromosys opened 3 years ago

dromosys commented 3 years ago

Please complete the following information:

Describe the Bug:

Using in preferences

<com.skydoves.colorpickerpreference.ColorPickerPreference alphaSlider="true" android:defaultValue="@color/title_color" android:key="@string/pref_key_color" android:summary="Set the color" android:title="ActionBar color" app:default_color="@color/app_background_default" app:preference_dialog_negative="@string/cancel" app:preference_dialog_positive="@string/ok" app:preference_dialog_title="Toolbar ColorPickerDialog" app:preference_palette="@drawable/palette" app:preference_selector="@drawable/wheel" />

include debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'

1 LIBRARY LEAKS

A Library Leak is a leak caused by a known bug in 3rd party code that you do not have control over.
See https://square.github.io/leakcanary/fundamentals-how-leakcanary-works/#4-categorizing-leaks

Leak pattern: instance field android.os.Message#obj
Description: A thread waiting on a blocking queue will leak the last dequeued object as a stack local reference. So when a HandlerThread becomes idle, it keeps a local reference to the last message it received. That message then gets recycled and can be used again. As long as all messages are recycled after being used, this won't be a problem, because these references are cleared when being recycled. However, dialogs create template Message instances to be copied when a message needs to be sent. These Message templates holds references to the dialog listeners, which most likely leads to holding a reference onto the activity in some way. Dialogs never recycle their template Message, assuming these Message instances will get GCed when the dialog is GCed. The combination of these two things creates a high potential for memory leaks as soon as you use dialogs. These memory leaks might be temporary, but some handler threads sleep for a long time. To fix this, you could post empty messages to the idle handler threads from time to time. This won't be easy because you cannot access all handler threads, but a library that is widely used should consider doing this for its own handler threads. This leaks has been shown to happen in both Dalvik and ART.
11971 bytes retained by leaking objects
Displaying only 1 leak trace out of 4 with the same signature
Signature: f0a7937f31106384afb5387b8bd9a23d56818914
┬───
│ GC Root: Java local variable
│
├─ android.os.HandlerThread thread
│    Leaking: UNKNOWN
│    Thread name: 'PlatformServiceBridgeHandlerThread'
│    ↓ HandlerThread.<Java Local>
│                    ~~~~~~~~~~~~
├─ android.os.Message instance
│    Leaking: UNKNOWN
│    ↓ Message.obj
│              ~~~
├─ com.skydoves.colorpickerview.ColorPickerDialog$Builder$2 instance
│    Leaking: UNKNOWN
│    Anonymous class implementing android.content.DialogInterface$OnClickListener
│    ↓ ColorPickerDialog$Builder$2.val$colorListener
│                                  ~~~~~~~~~~~~~~~~~
├─ com.skydoves.colorpickerpreference.ColorPickerPreference$onInit$$inlined$apply$lambda$1 instance
│    Leaking: UNKNOWN
│    Anonymous class implementing com.skydoves.colorpickerview.listeners.ColorEnvelopeListener
│    ↓ ColorPickerPreference$onInit$$inlined$apply$lambda$1.this$0
│                                                           ~~~~~~
├─ com.skydoves.colorpickerpreference.ColorPickerPreference instance
│    Leaking: UNKNOWN
│    ↓ ColorPickerPreference.mContext

Expected Behavior:

no memory leak!!