如何从内存转储中找出预加载的系统drawable(位图)的ID或名称

时间:2012-10-01 13:41:26

标签: android memory-management bitmap android-resources eclipse-memory-analyzer

我正在分析我们的应用程序的内存使用情况,并且发现了奇怪的Drawables,它经常“吃掉”几兆字节的堆。以下是MAT的几个屏幕截图:

Dominator tree 具有2个非常大的位图的Dominator树

path_to_gc_roots 上述位图之一的GC根路径

这个位图总是出现在我的手机( Samsung Galaxy Nexus,OS 4.1.1 )的堆转储中,无论我使用我们的应用程序多长时间或多么密集。

我已经尝试使用MAT搜索这个位图的来源 - 没有运气。我能找到的所有有用信息都是位图的widthheight,它们都是512x512: bitmap_info

但我们的应用程序没有任何单个512x512 drawables。我认为这是一些“系统”可绘制的。但到底是什么?为什么他们这么大?

我还查看了android.content.res.Resources类的源代码,搜索了sPreloadedDrawables字段的用法 - 也没有运气。我从内存转储获取的所有内容 - key来自sPreloadedDrawables数组,但我无法从此密钥中确定文件名或资源ID。

所以,我的问题是:

  • 如何确定此位图的名称或ID

  • 加载了这个巨大的位图是什么以及为什么它们总是留在内存中

更新

我找到了look at this bitmaps from memory dump的方法。这两个位图是一个简单的渐变,一个是黑色,另一个是白色。我想这是Holo.LightHolo.Dark ICS主题的资源。但我的第二个问题仍然是实际的:为什么这个位图总是停留在内存中?有没有办法上传或回收它们?

3 个答案:

答案 0 :(得分:0)

这张来自android.jar的图片,您必须将其包含在您的项目中。有两个垂直渐变的正方形。第一个 - 从0x000000到0x272d33,第二个 - 从0xe8e8e8到0xfafafa。 你可以在android.jar / res / drawable-nodpi / background_holo_dark.png和background_holo_light.png中找到它们。当然,根据您的Android SDK版本,您可以获得不同的结果。

答案 1 :(得分:0)

我猜他们会留在记忆中,因为他们是活动的默认背景。尝试在主题中指定不同的背景,看看它们是否仍在那里。

答案 2 :(得分:0)

预装的drawables由Zygote加载。

ZygoteInit#preloadResources()

    /**
 * Load in commonly used resources, so they can be shared across
 * processes.
 *
 * These tend to be a few Kbytes, but are frequently in the 20-40K
 * range, and occasionally even larger.
 */
private static void preloadResources() {
    final VMRuntime runtime = VMRuntime.getRuntime();

    try {
        mResources = Resources.getSystem();
        mResources.startPreloading();
        if (PRELOAD_RESOURCES) {
            Log.i(TAG, "Preloading resources...");

            long startTime = SystemClock.uptimeMillis();
            TypedArray ar = mResources.obtainTypedArray(
                    com.android.internal.R.array.preloaded_drawables);
            int N = preloadDrawables(runtime, ar);
            ar.recycle();
            Log.i(TAG, "...preloaded " + N + " resources in "
                    + (SystemClock.uptimeMillis()-startTime) + "ms.");


            startTime = SystemClock.uptimeMillis();
            ar = mResources.obtainTypedArray(
                    com.android.internal.R.array.preloaded_color_state_lists);
            N = preloadColorStateLists(runtime, ar);
            ar.recycle();
            Log.i(TAG, "...preloaded " + N + " resources in "
                    + (SystemClock.uptimeMillis()-startTime) + "ms.");
        }
        mResources.finishPreloading();
    } catch (RuntimeException e) {
        Log.w(TAG, "Failure preloading resources", e);
    }
}

你看,预装的drawable是com.android.internal.R.array.preloaded_drawables