Android 多个快速屏幕旋转上的位图/图层可绘制泄漏

Android 多个快速屏幕旋转上的位图/图层可绘制泄漏,android,bitmap,screen,orientation,memory-leaks,Android,Bitmap,Screen,Orientation,Memory Leaks,我在网上读了很多关于位图和屏幕旋转内存泄漏的帖子和评论 事实上,我遇到的问题很特别 我使用EclipseDDMS,并观察由1字节数组占用的堆内存,这些数组与放置在四个ImageView中的位图相关,每个位图位于ViewFlipper的一个页面中。 这些图像是从内存加载的,大小为216-220KB,我使用了一个可绘制的图层,以便在上面绘制另一个透明图像 注意位图占用的堆内存,如果我更改设备的方向,内存会增加一些MB。导致2-3 GC,几分钟后内存量减少到初始值。 缓慢地重复这个过程(更改方向+2-

我在网上读了很多关于位图和屏幕旋转内存泄漏的帖子和评论

事实上,我遇到的问题很特别

我使用EclipseDDMS,并观察由1字节数组占用的堆内存,这些数组与放置在四个ImageView中的位图相关,每个位图位于ViewFlipper的一个页面中。 这些图像是从内存加载的,大小为216-220KB,我使用了一个可绘制的图层,以便在上面绘制另一个透明图像

注意位图占用的堆内存,如果我更改设备的方向,内存会增加一些MB。导致2-3 GC,几分钟后内存量减少到初始值。 缓慢地重复这个过程(更改方向+2-3强制垃圾收集),内存量会增加,但随后会返回相同的值。 这使我认为我在应用程序中使用位图管理是正确的

但如果我开始反复快速旋转设备,我会看到内存量不断增加。。。。与快速旋转期间的快速增长相比,后续GC只能减少堆占用的内存量

Android不能如此快速地收集垃圾吗? 为什么我能够保持内存使用稳定,如果我慢慢旋转,而不是如果我重复旋转 在不强制GC的情况下更快

Android 4.1.2/三星Galaxy S3

每当从内部存储器读取png或下载png时,就会调用下面的代码 来自internet的异步任务。 禁用异步任务(因此通过后续轮换排除挂起的任务)不会 更改场景时,从内部存储加载两个“层”就足够了 启动以在旋转设备时快速填充堆

public void setBitmap(Bitmap bitmap) 
{
    try{
        Drawable layers[] = new Drawable[2];
        Bitmap fvgBackgroundBmp = BitmapFactory.decodeResource(getResources(), R.drawable.fvg_background2);
        layers[0] = new BitmapDrawable(getResources(), fvgBackgroundBmp);
        layers[1] = new BitmapDrawable(getResources(), bitmap);
        LayerDrawable layerDrawable = new LayerDrawable(layers);
        setImageDrawable(layerDrawable);
        mLayerDrawableAvailable = true;
    }
    catch(Exception outOfMemory)
    {
        Log.e("setBitmap got exception", outOfMemory.getLocalizedMessage());
    }
}
活动
onDestroy()
调用的方法
unbindDrawables()
没有帮助:

public void unbindDrawables()
{
    if(mLayerDrawableAvailable)
    {
        LayerDrawable lDrawable = (LayerDrawable) getDrawable();
        if(lDrawable != null)
        {   
            lDrawable.getDrawable(1).setCallback(null);
            lDrawable.getDrawable(0).setCallback(null);
            lDrawable.setCallback(null);
        }
    }
}

当内存压力较高时,不能保证调用onDestroy。这或许可以解释。尝试从onStop()调用unbindDrawables


我会尝试从您的图层中恢复位图,并将其回收

public void unbindDrawables()
{
    if(mLayerDrawableAvailable)
    {
        LayerDrawable lDrawable = (LayerDrawable) getDrawable();
        if(lDrawable != null)
        {   
            ((BitmapDrawable)lDrawable.getDrawable(1)).getBitmap().recycle();
            ((BitmapDrawable)lDrawable.getDrawable(0)).getBitmap().recycle();
            lDrawable.setCallback(null);
        }
    }
}

尝试在活动中的onDestroy()事件体中调用unbindDrawables()

我认为帮助你的唯一方法是,你提出一个最低限度的工作项目,该项目具有所描述的行为。然后有人可以测试它,看看会发生什么。