我正在分析我们的应用程序的内存使用情况,并且发现了奇怪的Drawables
,它经常“吃掉”几兆字节的堆。以下是MAT的几个屏幕截图:
具有2个非常大的位图的Dominator树
上述位图之一的GC根路径
这个位图总是出现在我的手机( Samsung Galaxy Nexus,OS 4.1.1 )的堆转储中,无论我使用我们的应用程序多长时间或多么密集。
我已经尝试使用MAT搜索这个位图的来源 - 没有运气。我能找到的所有有用信息都是位图的width
和height
,它们都是512x512:
但我们的应用程序没有任何单个512x512 drawables。我认为这是一些“系统”可绘制的。但到底是什么?为什么他们这么大?
我还查看了android.content.res.Resources
类的源代码,搜索了sPreloadedDrawables
字段的用法 - 也没有运气。我从内存转储获取的所有内容 - key
来自sPreloadedDrawables
数组,但我无法从此密钥中确定文件名或资源ID。
所以,我的问题是:
如何确定此位图的名称或ID ?
加载了这个巨大的位图是什么以及为什么它们总是留在内存中?
更新:
我找到了look at this bitmaps from memory dump的方法。这两个位图是一个简单的渐变,一个是黑色,另一个是白色。我想这是Holo.Light
和Holo.Dark
ICS主题的资源。但我的第二个问题仍然是实际的:为什么这个位图总是停留在内存中?有没有办法上传或回收它们?
答案 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