可能的内存泄漏(Android,Glide,活动堆栈)

时间:2017-03-31 09:34:39

标签: android memory-leaks android-glide activity-stack

作为OutOfMemory异常,我面临一个非常普遍和令人讨厌的问题。 介绍我的APP,它是重要的图片内容之一。我发现,我的设备(小米5s)收到256MB的OOM。我找不到内存泄漏(试过https://github.com/square/leakcanary)。我的APP在加载的第10个活动时崩溃了。 GC发生了奇怪的事情。只有当我完全回到起点时,大部分内存才会被释放。

对于图像加载我使用的是Glide。我将解码从8888更改为565(默认值)。随着8888 OOM发生得更快。

我在想的只是从堆栈开始完成活动。让我们说如果我们有8个活动,第9个活动开放,第1个活动将完成,依此类推。 在此之前,我想听听你们的建议!

修改 主要发生在尝试加载新活动并尝试加载图像时

  java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Failed to allocate a 331212 byte allocation with 254848 free bytes and 248KB until OOM
                                                                          at java.util.concurrent.FutureTask.report(FutureTask.java:94)
                                                                          at java.util.concurrent.FutureTask.get(FutureTask.java:164)
                                                                          at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor.afterExecute(FifoPriorityThreadPoolExecutor.java:96)
                                                                          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1121)
                                                                          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                          at java.lang.Thread.run(Thread.java:818)
                                                                          at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118)
                                                                       Caused by: java.lang.OutOfMemoryError: Failed to allocate a 331212 byte allocation with 254848 free bytes and 248KB until OOM
                                                                          at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
                                                                          at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
                                                                          at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635)
                                                                          at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611)
                                                                          at com.bumptech.glide.load.resource.bitmap.Downsampler.decodeStream(Downsampler.java:329)
                                                                          at com.bumptech.glide.load.resource.bitmap.Downsampler.downsampleWithSize(Downsampler.java:220)
                                                                          at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:153)
                                                                          at com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder.decode(StreamBitmapDecoder.java:50)
                                                                          at com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder.decode(StreamBitmapDecoder.java:19)
                                                                          at com.bumptech.glide.load.resource.bitmap.ImageVideoBitmapDecoder.decode(ImageVideoBitmapDecoder.java:39)
                                                                          at com.bumptech.glide.load.resource.bitmap.ImageVideoBitmapDecoder.decode(ImageVideoBitmapDecoder.java:20)
                                                                          at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decodeBitmapWrapper(GifBitmapWrapperResourceDecoder.java:121)
                                                                          at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decodeStream(GifBitmapWrapperResourceDecoder.java:94)
                                                                          at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:71)
                                                                          at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:61)
                                                                          at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperResourceDecoder.decode(GifBitmapWrapperResourceDecoder.java:22)
                                                                          at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperStreamResourceDecoder.decode(GifBitmapWrapperStreamResourceDecoder.java:24)
                                                                          at com.bumptech.glide.load.resource.gifbitmap.GifBitmapWrapperStreamResourceDecoder.decode(GifBitmapWrapperStreamResourceDecoder.java:14)
                                                                          at com.bumptech.glide.load.resource.file.FileToStreamDecoder.decode(FileToStreamDecoder.java:39)
                                                                          at com.bumptech.glide.load.resource.file.FileToStreamDecoder.decode(FileToStreamDecoder.java:17)
                                                                          at com.bumptech.glide.load.engine.DecodeJob.loadFromCache(DecodeJob.java:222)
                                                                          at com.bumptech.glide.load.engine.DecodeJob.decodeResultFromCache(DecodeJob.java:85)
                                                                          at com.bumptech.glide.load.engine.EngineRunnable.decodeFromCache(EngineRunnable.java:108)
                                                                          at com.bumptech.glide.load.engine.EngineRunnable.decode(EngineRunnable.java:99)
                                                                          at com.bumptech.glide.load.engine.EngineRunnable.run(EngineRunnable.java:58)
                                                                          at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
                                                                          at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                                                                          at java.lang.Thread.run(Thread.java:818) 
                                                                          at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:118) 

当内存几乎已经死亡时,也可以在打开活动时发生。

我认为这是正确的,在开启新活动时,旧的活动会在内存中加载图片 - >这意味着正在使用内存。但只开放10项活动相当少..图像大小为40-100kb。通常在活动中是> 20张图像。

我还使用了许多程序化创建的视图以及自定义适配器(APP相当大,我们刚刚发现了这个OOM问题)。我试图将不同的上下文传递到Glide / ImageViews,但内存使用似乎没有改变。

EDIT2 Heap dump at 178mb

1 个答案:

答案 0 :(得分:0)

我还有一个滑动的OOM问题,我解码了GIF并且我在Arraylist中保留了对drawables的引用,并且那些drawables没有被释放,解决方案是在arraylist中设置所有空值然后调用ArrayList.clear()。

/// Free drawables 
    for (int i = 0; i < mDrawables.size(); i++) {
                mDrawables.set(i, null);
            }      
            mDrawables.clear();