如何提高resources.getDrawable的性能

时间:2014-03-23 21:16:45

标签: java android performance garbage-collection

我有一个加载三个png图像的活动。在hdpi上,它们是20kb,148kb和190kb。这是我用以下代码加载它们的代码:

Drawable bronzePlaque = resources.getDrawable(R.drawable.bronze_plaque);
Drawable silverPlaque = resources.getDrawable(R.drawable.silver_plaque);
Drawable goldPlaque = resources.getDrawable(R.drawable.gold_plaque);

单独这些调用似乎需要大约500毫秒,这会在加载该活动时导致明显的延迟。

我不确定需要花多少时间才能拍到照片'大小,垃圾收集/堆大小增长,但我想尝试做一些事情来改善它。有没有办法可以让虚拟机正确地增加堆,垃圾收集只为这三个分配一次?

这里是这三行的logcat输出(以及围绕它们的系统打印getTimeInMillis)。

03-23 14:05:57.260: I/System.out(30302): time: 1395608757267
03-23 14:05:57.370: D/dalvikvm(30302): GC_FOR_ALLOC freed 39K, 4% free 7990K/8272K, paused 20ms, total 20ms
03-23 14:05:57.370: I/dalvikvm-heap(30302): Grow heap (frag case) to 8.968MB for 1188160-byte allocation
03-23 14:05:57.390: D/dalvikvm(30302): GC_FOR_ALLOC freed 1K, 4% free 9149K/9436K, paused 19ms, total 19ms
03-23 14:05:57.540: D/dalvikvm(30302): GC_FOR_ALLOC freed 1K, 4% free 9148K/9436K, paused 15ms, total 16ms
03-23 14:05:57.540: I/dalvikvm-heap(30302): Grow heap (frag case) to 10.245MB for 1340008-byte allocation
03-23 14:05:57.560: D/dalvikvm(30302): GC_FOR_ALLOC freed <1K, 3% free 10457K/10748K, paused 19ms, total 19ms
03-23 14:05:57.720: D/dalvikvm(30302): GC_FOR_ALLOC freed <1K, 3% free 10457K/10748K, paused 15ms, total 15ms
03-23 14:05:57.720: I/dalvikvm-heap(30302): Grow heap (frag case) to 11.482MB for 1297384-byte allocation
03-23 14:05:57.740: D/dalvikvm(30302): GC_FOR_ALLOC freed <1K, 3% free 11724K/12016K, paused 18ms, total 18ms
03-23 14:05:57.760: I/System.out(30302): time: 1395608757770

我知道,一旦加载了该活动,以后加载活动的速度就会快得多。我应该在app加载时加载一次这些图像,以帮助防止痛苦的堆积/垃圾收集?我点击前面加载的滞后时间比单击活动时经历的滞后半秒。

2 个答案:

答案 0 :(得分:1)

尝试从另一个线程(即不是主线程)加载这些图像。除了在gc中花费大约100毫秒之外,500毫秒的其余部分用于从文件系统加载数据并将JPG数据解压缩到位图中。

  

我知道在活动加载后,它会更快   稍后加载活动。我应该在一次加载这些图像吗?   app加载时间,以帮助防止痛苦的堆增长/垃圾   收集?

除非您有意识地保留解码的位图,否则资源可以自由发布它认为合适的任何缓存的Drawable / Bitmap。请注意,图像将占用750x502x4 + 750x567x4 + 750x549x4 = ~4.5 MB RAM,有目的地保留它们可能在旧设备上有其他分支,例如OoM(Nexus One每个进程/应用程序最多只有16 MB RAM)导致您的应用程序在后台运行时需要更快地从内存中逐出,并且操作系统需要更多内存。

答案 1 :(得分:1)

好像你运气不好。您无法根据需要增加Android上的堆(与普通JVM进程不同)。请参阅here仍有4 MB图像太多。

似乎你已经有了解决方案,请先加载它们。