HBiSoft / HBRecorder

Lightweight screen recording Android library
MIT License
407 stars 138 forks source link

Memory Leak #117

Closed sofronovicnikola closed 2 years ago

sofronovicnikola commented 2 years ago

Describe the bug Facing OutOfMemory exceptions due to memory leaks coming from your library. Memory leaks are being detected after hbRecorder.stopScreenRecording() is called.

Log Logs are from LeakCanary.

0 APPLICATION LEAKS

References underlined with "~~~" are likely causes.
Learn more at https://squ.re/leaks.
====================================
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.media.projection.MediaProjection$MediaProjectionCallback#this$0
Description: MediaProjectionCallback is held by another process, and holds on to MediaProjection
which has an activity as its context.
363868 bytes retained by leaking objects
Signature: cf05e5fc38dfaf3690c402eff8a119e02748944c
┬───
│ GC Root: Global variable in native code
│
├─ android.media.projection.MediaProjection$MediaProjectionCallback instance
│    Leaking: UNKNOWN
│    Retaining 364.7 kB in 6596 objects
│    Library leak match: instance field android.media.projection.MediaProjection$MediaProjectionCallback#this$0
│    ↓ MediaProjection$MediaProjectionCallback.this$0
│                                              ~~~~~~
├─ android.media.projection.MediaProjection instance
│    Leaking: UNKNOWN
│    Retaining 364.7 kB in 6595 objects
│    mContext instance of android.app.ContextImpl
│    ↓ MediaProjection.mContext
│                      ~~~~~~~~
├─ android.app.ContextImpl instance
│    Leaking: UNKNOWN
│    Retaining 364.6 kB in 6589 objects
│    mOuterContext instance of com.hbisoft.hbrecorder.ScreenRecordService
│    ContextImpl.mOuterContext is an instance of com.hbisoft.hbrecorder.ScreenRecordService
│    ↓ ContextImpl.mOuterContext
│                  ~~~~~~~~~~~~~
╰→ com.hbisoft.hbrecorder.ScreenRecordService instance
​     Leaking: YES (ObjectWatcher was watching this because com.hbisoft.hbrecorder.ScreenRecordService received
​     Service#onDestroy() callback and Service not held by ActivityThread)
​     Retaining 363.9 kB in 6573 objects
​     key = 8d4c40b7-3c66-4f9a-a8d9-f9c154d6e4af
​     watchDurationMillis = 45140
​     retainedDurationMillis = 40131

HBRecorder version 2.0.4

Device information

HBiSoft commented 2 years ago

Is your application in the foreground when stopping the recording?

sofronovicnikola commented 2 years ago

Yes

HBiSoft commented 2 years ago

That's strange. Let me run it on the library itself. Give me some time and I will get back to you.

sofronovicnikola commented 2 years ago

Any updates? Thanks.

HBiSoft commented 2 years ago

@sofronovicnikola My apologies for the late reply.

I was able to see the leak, however, I don't know how and why it is happening. I saw this answer, which eliminates this leak, but then I get the following leak:

┬───
│ GC Root: Global variable in native code
│
├─ android.hardware.display.DisplayManagerGlobal$VirtualDisplayCallback instance
│    Leaking: UNKNOWN
│    Retaining 12,9 kB in 60 objects
│    ↓ DisplayManagerGlobal$VirtualDisplayCallback.mDelegate
│                                                  ~~~~~~~~~
├─ android.hardware.display.DisplayManagerGlobal$VirtualDisplayCallbackDelegate
│  instance
│    Leaking: UNKNOWN
│    Retaining 12,3 kB in 59 objects
│    ↓ DisplayManagerGlobal$VirtualDisplayCallbackDelegate.mCallback
│                                                          ~~~~~~~~~
├─ com.hbisoft.hbrecorder.ScreenRecordService$3 instance
│    Leaking: UNKNOWN
│    Retaining 12,3 kB in 58 objects
│    Anonymous subclass of android.hardware.display.VirtualDisplay$Callback
│    this$0 instance of com.hbisoft.hbrecorder.ScreenRecordService
│    ↓ ScreenRecordService$3.this$0
│                            ~~~~~~
╰→ com.hbisoft.hbrecorder.ScreenRecordService instance
​     Leaking: YES (ObjectWatcher was watching this because com.hbisoft.
​     hbrecorder.ScreenRecordService received Service#onDestroy() callback and
​     Service not held by ActivityThread)
​     Retaining 12,3 kB in 57 objects
​     key = f033983a-70f2-41e7-95c3-63373719a6a0
​     watchDurationMillis = 54328
​     retainedDurationMillis = 49324
​     mApplication instance of android.app.Application
​     mBase instance of android.app.ContextImpl

The problem seems to come from here

I have no idea how to resolve this, but I will keep doing research. You are more than welcome to download the project and try and figure it out as well.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed if no further activity occurs within the next 3 days. Thank you for your contributions.

bomberaya commented 2 years ago

@HBiSoft could you please check if this PR fixes the issue, thanks!