koral--/android-gif-drawable

memory leak when gif infinite loop

mowwwcom opened this issue · 3 comments

At first, the Native Heap is 30M, but after run 12 hours, the Native Heap is up to 152M. the app just show 10 pieces of gif photo, but do nothing. I guess the memory leak maybe caused by 'android-gif-drawable' lib.

With that info I can do nothing.
Could you create a minimal sample project which reproduces this issue?

  1. Sample Code

I create a mini demo reproduced this issuse. https://github.com/mowwwcom/GifDemo.git
The targe devices is 'CPU/ABI: Google APIs Intel Atom (x86_64) Target: google_apis [Google APIs] (API level 28)'

The main sample code is:

    private void addViews() {
        for (int i = 0; i < 10; ++i) {
            GifImageView iv = new GifImageView(this);
            try {
                GifDrawable gifDrawable = new GifDrawable(getResources(), R.mipmap.gif4);
                iv.setImageDrawable(gifDrawable);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mContainer.addView(iv);
        }
    }
  1. Dump meminfo
    Use follow command to dump meminfo.
    adb shell dumpsys meminfo com.mo.gifdemo

2.1 Fisrt Time dump
At 2021-2-3 20:21, the Native Heap is 24860KB (24MB)

Applications Memory Usage (in Kilobytes):
Uptime: 337826592 Realtime: 337826592

** MEMINFO in pid 2975 [com.mo.gifdemo] **
                   Pss  Private  Private  SwapPss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap    25031    24860        0        0    34816    29523     5292
  Dalvik Heap     2157     2040        0        0     3420     1726     1694
 
 App Summary
                       Pss(KB)
                        ------
           Java Heap:     8452
         Native Heap:    24860
                Code:     7440
               Stack:       76
            Graphics:        0
       Private Other:     1396
              System:    12132
 
               TOTAL:    54356       TOTAL SWAP PSS:        0

2.1.2 First Time dump malloc
Use pmap to catch native memory location

generic_x86_64:/ # pmap 2975 -x |grep malloc
Address            Kbytes     PSS   Dirty    Swap  Mode  Mapping
000074497c800000    6144    4108    4108       0 rw---    [anon:libc_malloc]
000074497d600000    6144    4096    4096       0 rw---    [anon:libc_malloc]
000074497de00000   10240    4380    4380       0 rw---    [anon:libc_malloc]
000074497ea00000    8192    7376    7376       0 rw---    [anon:libc_malloc]
000074498d200000    2048    1223    1172       0 rw---    [anon:libc_malloc]
000074498e000000    2048    1952    1952       0 rw---    [anon:libc_malloc]
0000744990000000    2048    1536    1536       0 rw---    [anon:libc_malloc]
0000744995400000    2048    1006     936       0 rw---    [anon:libc_malloc]
0000744996000000    4096    1370    1320       0 rw---    [anon:libc_malloc]
0000744996466000     300      10       0       0 r-x--  libc_malloc_debug.so
00007449964b2000      12       0       0       0 r----  libc_malloc_debug.so
00007449964b5000       4       4       4       0 rw---  libc_malloc_debug.so

2.2 Second Time dump meminfo
At 2021-2-4 09:22, the Native Heap is 284928KB (278MB)

Applications Memory Usage (in Kilobytes):
Uptime: 385920843 Realtime: 385920843

** MEMINFO in pid 2975 [com.mo.gifdemo] **
                   Pss  Private  Private  SwapPss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap   285114   284928        0        0   294912   289022     5889
  Dalvik Heap     2300     2168        0        0     3422     1727     1695
 Dalvik Other      869      868        0        0
        Stack       76       76        0        0
       Ashmem        5        0        0        0
    Other dev        8        0        8        0
     .so mmap     1339      152       84        0
    .apk mmap     2532     2532        0        0
    .dex mmap      346      244       48        0
    .oat mmap       11        0        0        0
    .art mmap     6217     6080        4        0
   Other mmap       16        4        0        0
      Unknown      586      564        0        0
        TOTAL   299419   297616      144        0   298334   290749     7584

 App Summary
                       Pss(KB)
                        ------
           Java Heap:     8252
         Native Heap:   284928
                Code:     3060
               Stack:       76
            Graphics:        0
       Private Other:     1444
              System:     1659

               TOTAL:   299419       TOTAL SWAP PSS:        0

2.2.2 Second Time dump malloc
Use pmap to catch native memory location

generic_x86_64:/ # pmap 2975 -x |grep malloc
Address            Kbytes     PSS   Dirty    Swap  Mode  Mapping
000074495d000000  522240  262156  262156       0 rw---    [anon:libc_malloc]
000074497d600000    6144    4096    4096       0 rw---    [anon:libc_malloc]
000074497de00000   10240    4292    4292       0 rw---    [anon:libc_malloc]
000074497ea00000    8192    7388    7388       0 rw---    [anon:libc_malloc]
000074498d200000    2048    1240    1184       0 rw---    [anon:libc_malloc]
000074498e000000    2048    1952    1952       0 rw---    [anon:libc_malloc]
0000744990000000    2048    1588    1588       0 rw---    [anon:libc_malloc]
0000744995400000    2048    1020     944       0 rw---    [anon:libc_malloc]
0000744996000000    4096    1386    1332       0 rw---    [anon:libc_malloc]
0000744996466000     300       4       0       0 r-x--  libc_malloc_debug.so
00007449964b2000      12       0       0       0 r----  libc_malloc_debug.so
00007449964b5000       4       4       4       0 rw---  libc_malloc_debug.so

You can see the native memory is leaked by malloc.

Finally, I found that this memory leak is android draw cache. after Activity onStop, this memory cleared by system.