3

当我预计会增加约 0.1 MB 时,我会增加 6 MB 的本机堆使用量

我是如何得出这些数字的:

Log.d("test", "before setting layout");
showMemoryStats();

setContentView(R.layout.my_layout);

Log.d("test", "after setting layout");
showMemoryStats();

showMemoryStats 在哪里:

public static void showMemoryStats() {
    Log.i("test", "----------------------------------------------------------------------------------------------------------------------------");
    Log.i("test", "showing memory stats in xx");
    double nativeUsage = Debug.getNativeHeapAllocatedSize(); 
    Log.i("test", "nativeUsage: " + nativeUsage);
    //current heap size 
    double heapSize =  Runtime.getRuntime().totalMemory();
    Log.i("test", "heapSize: " + heapSize);
    //amount available in heap 
    double heapRemaining = Runtime.getRuntime().freeMemory();   
    Log.i("test", "heapRemaining: " + heapRemaining);
    double memoryAvailable = Runtime.getRuntime().maxMemory() - (heapSize - heapRemaining) - nativeUsage;
    Log.i("test", "memoryAvailable: " + memoryAvailable);
    Log.i("test", "----------------------------------------------------------------------------------------------------------------------------");
}

输出:

07-03 16:50:40.127: D/test(18647): 在设置布局之前

07-03 16:50:40.127: I/test(18647): ---------------------------------- -------------------------------------------------- --------------------------------------

07-03 16:50:40.127: I/test(18647): 在 xx 中显示内存统计信息

07-03 16:50:40.127: I/test(18647): nativeUsage: 5706008.0

07-03 16:50:40.127: I/test(18647): heapSize: 4905968.0

07-03 16:50:40.127: I/test(18647): heapRemaining: 1815456.0

07-03 16:50:40.127: I/test(18647): memoryAvailable: 2.4757912E7

07-03 16:50:40.127: I/test(18647): ---------------------------------- -------------------------------------------------- --------------------------------------

07-03 16:50:40.348: D/dalvikvm(18647): GC_EXTERNAL_ALLOC 释放 100K,49% 释放 2924K/5639K,外部 0K/0K,暂停 45ms

07-03 16:50:40.518: D/dalvikvm(18647): GC_EXTERNAL_ALLOC 释放 9K,49% 释放 2917K/5639K,外部 2700K/3371K,暂停 51ms

07-03 16:50:40.638: D/dalvikvm(18647): GC_EXTERNAL_ALLOC 释放 4K,49% 释放 2928K/5639K,外部 3952K/4356K,暂停 51ms

07-03 16:50:40.698: D/dalvikvm(18647): GC_EXTERNAL_ALLOC 释放 2K,48% 释放 2933K/5639K,外部 5963K/6027K,暂停 24ms

07-03 16:50:40.718: D/test(18647): 设置布局后

07-03 16:50:40.718: I/test(18647): ---------------------------------- -------------------------------------------------- --------------------------------------

07-03 16:50:40.718: I/test(18647): 在 xx 中显示内存统计信息

07-03 16:50:40.718: I/test(18647): nativeUsage: 1.2101904E7

07-03 16:50:40.718: I/test(18647): heapSize: 4734944.0

07-03 16:50:40.718: I/test(18647): heapRemaining: 1716432.0

07-03 16:50:40.718: I/test(18647): memoryAvailable: 1.8434016E7

07-03 16:50:40.718: I/test(18647): ---------------------------------- -------------------------------------------------- --------------------------------------

数学:

12101856 字节 - 5703424 字节 = 6398432 字节 = 6.10202 mb

我浏览了我的布局文件并添加了所有使用的可绘制对象的大小,总大小为 124 kb -> 0.121094 mb

那么到底是什么导致本机堆增加 6 mb 呢?

我可以放置布局文件,如果有人要求,不知道这是否有意义......只是一堆带有 id 和 drawable 的布局,正如我所说的,我已经检查了 drawable 的大小。

非常感谢提前...

编辑:在我的情况下,这是解决方案 - 为了总结响应和评论:我将图像存储在“可绘制”文件夹中并使用 hdpi 设备。解决方案:将图像放在文件夹 drawable-hdpi 中。原因:系统将我的图像从“drawable”拉伸以匹配 hdpi 分辨率,尽管它们已经是 hdpi 分辨率。这使得它们占用的内存超出了应有的 2 倍。

4

2 回答 2

1

问题是当android必须在屏幕上绘制你的drawable时,它们比它们在你的res文件夹中要大得多。例如,如果您有一个 100 Kb 的 PNG,那么这就是压缩后的大小。当 android 在屏幕上绘制 PNG 时,它会将其放大到默认大小(4 字节)*(像素高度)*(像素宽度)的正常大小。这是因为它为图像的每个像素存储 4 个字节的颜色信息。这意味着如果您的图像是例如 800 x 600 像素,那么 android 生成的结果位图是 800x600x4 字节 = 1920000 字节 = 接近 2 Mb。

如果你想解决这个问题,你必须使用较小的图像。

于 2012-07-03T15:53:21.323 回答
1

好吧,位图占用了大量空间。

每个像素需要 4 个字节!

所以一个1M像素的图片就是4MB!!!我假设您正在使用许多较小的图像,但它们很快就会加起来。

解决此问题的一种方法是以较低的分辨率加载位图(在大多数情况下,您不会注意到任何差异,因为它们无论如何都不会以最大分辨率显示)。对此BitmapFactory.Options.inSampleSize进行调查。

引用自 android

位图占用大量内存,尤其是对于照片等丰富的图像。例如,Galaxy Nexus 上的相机可拍摄高达 2592x1936 像素(5 兆像素)的照片。如果使用的位图配置是 ARGB_8888(Android 2.3 以后的默认配置),则将此图像加载到内存中大约需要 19MB 内存(2592*1936*4 字节),立即耗尽某些设备上的每个应用程序的限制。

这是一个很好的链接,可以更好地解释它

于 2012-07-03T15:53:53.820 回答