How to find out IDs or names of preloaded system d

2019-03-20 18:19发布

I'm analyzing memory usage of our app, and has found strange Drawables, which constantly "eats" few megabytes of heap. Here are few screenshots from MAT:

Dominator tree Dominator tree with 2 pretty big bitmaps

path_to_gc_roots Path to GC roots for one of above bitmaps

This bitmaps always appears in heap dumps from my phone (Samsung Galaxy Nexus, OS 4.1.1), no matter how long or how intensive I use our app.

I've already tried to search the source of this bitmaps using MAT - with no luck. All usefull information I was able to find waswidth and height of bitmaps, it's both 512x512: bitmap_info

But our app doesn't have any single 512x512 drawables. I assume this is some "system" drawables. But what exactly? Why them so big?

I've also looked at source code of android.content.res.Resources class, searching usage of sPreloadedDrawables field - also with no luck. All I get from memory dump - is key from sPreloadedDrawables array, but I can't determine filename or resource id from this key.

So, my questions is:

  • how can I determine names or IDs of this bitmaps?

  • what for this huge bitmaps are loaded and why they always stays in memory?

Update:

I have found a way to look at this bitmaps from memory dump. This two bitmaps is a simple gradients, one black, other - white. I suppose this is resources for Holo.Light and Holo.Dark ICS themes. But my second question is still actual: why this bitmaps are always stays in memory? Is there any way to upload or recycle them?

3条回答
Evening l夕情丶
2楼-- · 2019-03-20 18:32

The preloaded drawables are loaded by 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);
    }
}

You see, the preloaded drawables are com.android.internal.R.array.preloaded_drawables

查看更多
甜甜的少女心
3楼-- · 2019-03-20 18:42

This picture from android.jar, which you have to include into your project. There are two squares with the vertical gradient. The first - from 0x000000 to 0x272d33, the second - from 0xe8e8e8 to 0xfafafa. You can find them in android.jar/res/drawable-nodpi/background_holo_dark.png and background_holo_light.png. Of course, you can get different results depending on your Android SDK version.

查看更多
Evening l夕情丶
4楼-- · 2019-03-20 18:56

I would guess they stay in memory because they are the default backgrounds for activities. Try specifying a different background in your theme and see if they are still there.

查看更多
登录 后发表回答