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:
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:
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?
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.
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.
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
来源:https://stackoverflow.com/questions/12674484/how-to-find-out-ids-or-names-of-preloaded-system-drawables-bitmaps-from-memory