一次内存泄漏的问题记录

时间:2024-04-05 09:30:50

项目场景:

同事在开发一款人脸识别app时,在多次执行,打开--》人脸识别--》关闭--》打开循环测试过程中会耗尽内存导致被kill。


问题描述:

测试同学通过用monkey脚本测试,遇到内存泄漏的问题。

 

  • 日志片段1:可以看到系统一直在频繁gc,已经超过设定的512mb上限。

09-22 13:53:21.106  3052  3127 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:21.630  3052  5107 I zygote  : Clamp target GC heap from 535MB to 512MB
09-22 13:53:21.630  3052  5107 I zygote  : Alloc concurrent copying GC freed 38(1192B) AllocSpace objects, 0(0B) LOS objects, 0% free, 511MB/512MB, paused 167us total 1.441s
09-22 13:53:21.630  3052  3142 I zygote  : WaitForGcToComplete blocked Alloc on HeapTrim for 2.013s
09-22 13:53:21.630  3052  5107 W zygote  : Throwing OutOfMemoryError "Failed to allocate a 460812 byte allocation with 1192 free bytes and 1192B until OOM, max allowed footprint 536870912, growth limit 536870912"
09-22 13:53:21.630  3052  3142 I zygote  : Starting a blocking GC Alloc
09-22 13:53:21.630  3052  3142 I zygote  : Starting a blocking GC Alloc
09-22 13:53:21.630  3052  4168 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:21.630  3052  5107 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:21.630  3052  3806 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:21.630  3052  3127 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:21.630  3052  3061 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.103  3052  3142 I zygote  : Clamp target GC heap from 535MB to 512MB
09-22 13:53:22.103  3052  3142 I zygote  : Alloc concurrent copying GC freed 30(808B) AllocSpace objects, 0(0B) LOS objects, 0% free, 511MB/512MB, paused 145us total 472.588ms
09-22 13:53:22.103  3052  4168 I zygote  : WaitForGcToComplete blocked Alloc on HeapTrim for 2.484s
09-22 13:53:22.103  3052  4168 I zygote  : Starting a blocking GC Alloc
09-22 13:53:22.103  3052  4168 I zygote  : Starting a blocking GC Alloc
09-22 13:53:22.103  3052  3142 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.103  3052  3127 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.103  3052  3061 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.103  3052  3806 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.103  3052  5107 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.557  3052  4168 I zygote  : Clamp target GC heap from 535MB to 512MB
09-22 13:53:22.557  3052  4168 I zygote  : Alloc concurrent copying GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 0% free, 511MB/512MB, paused 131us total 453.636ms
09-22 13:53:22.557  3052  3127 I zygote  : WaitForGcToComplete blocked Alloc on HeapTrim for 1.451s
09-22 13:53:22.557  3052  3127 I zygote  : Starting a blocking GC Alloc
09-22 13:53:22.557  3052  3142 I zygote  : WaitForGcToComplete blocked Alloc on HeapTrim for 454.347ms
09-22 13:53:22.558  3052  3142 I zygote  : Starting a blocking GC Alloc
09-22 13:53:22.558  3052  3061 I zygote  : WaitForGcToComplete blocked Alloc on HeapTrim for 2.941s
09-22 13:53:22.558  3052  3061 I zygote  : Starting a blocking GC Alloc
09-22 13:53:22.558  3052  3061 I zygote  : Starting a blocking GC Alloc
09-22 13:53:22.558  3052  3806 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.558  3052  5107 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.558  3052  4168 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.558  3052  3142 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:22.558  3052  3127 I zygote  : Waiting for a blocking GC Alloc
09-22 13:53:23.032  3052  3061 I zygote  : Clamp target GC heap from 535MB to 512MB
09-22 13:53:23.032  3052  3061 I zygote  : Alloc concurrent copying GC freed 23(552B) AllocSpace objects, 0(0B) LOS objects, 0% free, 511MB/512MB, paused 120us total 474.598ms
09-22 13:53:23.033  3052  3806 I zygote  : WaitForGcToComplete blocked Alloc on HeapTrim for 2.804s
09-22 13:53:23.033  3052  3806 I zygote  : Starting a blocking GC Alloc

  • 日志片段2:已经无法再分配新的内存空间

09-22 13:53:30.408  3052  3142 W System.err: java.lang.RuntimeException: Exception while computing database live data.
09-22 13:53:30.409  3052  3142 W System.err:     at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92)
09-22 13:53:30.409  3052  3142 W System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
09-22 13:53:30.409  3052  3142 W System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
09-22 13:53:30.409  3052  3142 W System.err:     at java.lang.Thread.run(Thread.java:764)
09-22 13:53:30.409  3052  3142 W System.err: Caused by: android.database.sqlite.SQLiteException: unknown error (code 0): Native could not create new byte[]
09-22 13:53:30.409  3052  3142 W System.err:     at android.database.CursorWindow.nativeGetBlob(Native Method)
09-22 13:53:30.410  3052  3142 W System.err:     at android.database.CursorWindow.getBlob(CursorWindow.java:403)
09-22 13:53:30.410  3052  3142 W System.err:     at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:45)
09-22 13:53:30.410  3052  3142 W System.err:     at com.decard.facediscernoffline.module_base_offline.bean.db.FaceDataDao_Impl$10.call(FaceDataDao_Impl.java:1032)
09-22 13:53:30.410  3052  3142 W System.err:     at com.decard.facediscernoffline.module_base_offline.bean.db.FaceDataDao_Impl$10.call(FaceDataDao_Impl.java:1016)
09-22 13:53:30.410  3052  3142 W System.err:     at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:90)
09-22 13:53:30.410  3052  3142 W System.err:     ... 3 more

原因分析:

  • 1,查询此设备的DVM分配的heap上限

adb shell getprop | grep heap  

[dalvik.vm.heapsize]: [512m]

  • 2,重复复现步骤,抓取内存申请快照hprof文件

adb shell am dumpheap com.xxx.xxx  /data/local/tmp/14_54.hprof

hprof-conv 14_54.hprof 14_54_R.hprof  

hprof-conv在sdk的platform-tools目录

 

  • 3,使用Memory Analyzer Tool进行分析

打开14_54_R.hprof 文件后,

一次内存泄漏的问题记录

竟然有多个activity实例,基本断定是发生了上下文的强引用导致Activity无法被回收。

 

  • 4,点击右键Paths to GC Roots-->exclude all phantom/weak/soft etc reference

一次内存泄漏的问题记录

发现引用的代码位置,进行排查,发现使用的都是activity的context。


解决方案:

重构代码,把需要引用上下文对象的类,都用ApplicationContext 来代替。