5

我正在分析我们应用程序的内存使用情况,发现奇怪Drawables,它不断“吃掉”几兆字节的堆。以下是MAT的几张截图:

支配树 具有 2 个非常大的位图的支配树

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

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

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

但是我们的应用程序没有任何单一的 512x512 可绘制对象。我认为这是一些“系统”可绘制对象。但究竟是什么?为什么它们这么大?

我还查看了android.content.res.Resources类的源代码,搜索字段的用法sPreloadedDrawables- 也没有运气。我从内存转储中得到的只是key来自sPreloadedDrawables数组,但我无法从这个键中确定文件名或资源 ID。

所以,我的问题是:

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

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

更新

我找到了一种从内存转储中查看此位图的方法。这两个位图是一个简单的渐变,一个是黑色,另一个是白色。我想这是ICS 主题Holo.Light的资源。Holo.Dark但是我的第二个问题仍然是实际的:为什么这个位图总是留在内存中?有没有办法上传或回收它们?

4

3 回答 3

0

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

于 2012-10-01T15:13:54.197 回答
0

我猜它们会留在内存中,因为它们是活动的默认背景。尝试在您的主题中指定不同的背景,看看它们是否仍然存在。

于 2012-10-05T15:17:01.053 回答
0

预加载的可绘制对象由 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

于 2017-04-21T08:42:23.143 回答