2

我有一个 ViewPager,pageOffscreenPageLimit 设置为 1(总共 3 页)。我用它为每页显示 4 个位图。位图是异步加载的、按比例缩小的,所有这些都是为了避免 OutOfMemory 异常。由于 GC,我注意到一些“摊位”滚动页面,这里有一些日志:

03-22 13:05:06.320: V/test(11448): onPageSelected(2)
03-22 13:05:06.840: V/test(11448): destroyItem(0)
03-22 13:05:06.850: V/test(11448): instantiateItem(3)
03-22 13:05:06.900: D/dalvikvm(11448): GC_FOR_ALLOC freed 4578K, 29% free 15567K/21703K, paused 24ms
03-22 13:05:06.900: I/dalvikvm-heap(11448): Grow heap (frag case) to 18.265MB for 3128360-byte allocation
03-22 13:05:06.930: D/dalvikvm(11448): GC_FOR_ALLOC freed <1K, 15% free 18622K/21703K, paused 27ms
03-22 13:05:06.990: D/dalvikvm(11448): GC_CONCURRENT freed 49K, 15% free 18636K/21703K, paused 1ms+4ms
03-22 13:05:07.060: D/dalvikvm(11448): GC_FOR_ALLOC freed 3221K, 25% free 16298K/21703K, paused 21ms
03-22 13:05:07.060: I/dalvikvm-heap(11448): Grow heap (frag case) to 18.979MB for 3128360-byte allocation
03-22 13:05:07.100: D/dalvikvm(11448): GC_CONCURRENT freed <1K, 11% free 19353K/21703K, paused 1ms+3ms
03-22 13:05:07.170: D/dalvikvm(11448): GC_FOR_ALLOC freed 3130K, 22% free 17026K/21703K, paused 20ms
03-22 13:05:07.170: I/dalvikvm-heap(11448): Grow heap (frag case) to 19.694MB for 3131424-byte allocation
03-22 13:05:07.210: D/dalvikvm(11448): GC_CONCURRENT freed <1K, 8% free 20084K/21703K, paused 1ms+3ms
03-22 13:05:07.240: V/test(11448): onPageSelected(3)
03-22 13:05:07.270: D/dalvikvm(11448): GC_FOR_ALLOC freed 42K, 8% free 20053K/21703K, paused 22ms
03-22 13:05:07.270: I/dalvikvm-heap(11448): Grow heap (frag case) to 20.359MB for 729656-byte allocation
03-22 13:05:07.290: D/dalvikvm(11448): GC_FOR_ALLOC freed <1K, 8% free 20765K/22471K, paused 20ms
03-22 13:05:07.320: D/dalvikvm(11448): GC_FOR_ALLOC freed 3094K, 22% free 17739K/22471K, paused 19ms
03-22 13:05:07.330: I/dalvikvm-heap(11448): Grow heap (frag case) to 20.386MB for 3128360-byte allocation
03-22 13:05:07.350: D/dalvikvm(11448): GC_FOR_ALLOC freed <1K, 8% free 20793K/22471K, paused 20ms
03-22 13:05:07.390: D/dalvikvm(11448): GC_CONCURRENT freed 2K, 8% free 20799K/22471K, paused 1ms+3ms
03-22 13:05:07.490: D/dalvikvm(11448): GC_FOR_ALLOC freed 38K, 8% free 20772K/22471K, paused 27ms
03-22 13:05:07.490: I/dalvikvm-heap(11448): Grow heap (frag case) to 21.061MB for 729656-byte allocation
03-22 13:05:07.520: D/dalvikvm(11448): GC_FOR_ALLOC freed <1K, 8% free 21484K/23239K, paused 21ms
03-22 13:05:07.760: V/test(11448): destroyItem(1)
03-22 13:05:07.760: V/test(11448): instantiateItem(4)
03-22 13:05:07.820: D/dalvikvm(11448): GC_FOR_ALLOC freed 6063K, 34% free 15558K/23239K, paused 24ms
03-22 13:05:07.820: I/dalvikvm-heap(11448): Grow heap (frag case) to 18.526MB for 3411216-byte allocation
03-22 13:05:07.850: D/dalvikvm(11448): GC_FOR_ALLOC freed 19K, 19% free 18869K/23239K, paused 19ms
03-22 13:05:07.900: D/dalvikvm(11448): GC_CONCURRENT freed 6K, 19% free 18908K/23239K, paused 1ms+4ms
03-22 13:05:07.960: D/dalvikvm(11448): GC_FOR_ALLOC freed 3463K, 30% free 16334K/23239K, paused 20ms
03-22 13:05:07.960: I/dalvikvm-heap(11448): Grow heap (frag case) to 19.284MB for 3411216-byte allocation
03-22 13:05:07.980: D/dalvikvm(11448): GC_FOR_ALLOC freed 0K, 16% free 19665K/23239K, paused 21ms
03-22 13:05:08.030: D/dalvikvm(11448): GC_CONCURRENT freed 5K, 16% free 19674K/23239K, paused 1ms+3ms
03-22 13:05:08.100: D/dalvikvm(11448): GC_FOR_ALLOC freed 3433K, 27% free 17033K/23239K, paused 22ms
03-22 13:05:08.100: I/dalvikvm-heap(11448): Grow heap (frag case) to 19.966MB for 3411216-byte allocation
03-22 13:05:08.140: D/dalvikvm(11448): GC_CONCURRENT freed <1K, 13% free 20363K/23239K, paused 2ms+3ms
03-22 13:05:08.220: D/dalvikvm(11448): GC_FOR_ALLOC freed 3407K, 24% free 17749K/23239K, paused 19ms
03-22 13:05:08.220: I/dalvikvm-heap(11448): Grow heap (frag case) to 20.666MB for 3411216-byte allocation
03-22 13:05:08.260: D/dalvikvm(11448): GC_CONCURRENT freed 1K, 10% free 21079K/23239K, paused 1ms+4ms

堆大小保持在 24Mb 并且不会增长。此外,在destroyItem 中,我尝试释放ImageView,将drawables 和回调设置为null。我可以提高性能还是这是正常行为?

4

1 回答 1

3

考虑到您正在使用Viewpager 和 Imageviews,我想您有两个选择

关于图像视图尝试使用强大的Android图像下载和缓存库,如Picasso,最新的Volley Imageloading(对大尺寸图像非常有帮助)以有效的方式提高图像加载能力。

关于 Viewpager你必须使用高效的适配器FragmentStatePagerAdapter:这个版本的分页器在有大量页面时更有用,更像是一个列表视图。当页面对用户不可见时,它们的整个片段可能会被销毁,只保留该片段的已保存状态。与 FragmentPagerAdapter 相比,这允许分页器保留与每个访问的页面相关联的内存少得多,但代价是在页面之间切换时可能会产生更多开销。

请在使用 FragmentPagerAdapter 之前考虑一下,因为它将整个片段存储在内存中,如果在 ViewPager 中使用大量片段,可能会增加内存开销。相反,它的兄弟,FragmentStatePagerAdapter 只存储片段的 savedInstanceState,并在失去焦点时销毁所有片段。因此,当我们必须使用动态片段时应该使用 FragmentStatePagerAdapter,例如带有小部件的片段,因为它们的数据可以存储在 savedInstanceState 中。即使有大量碎片也不会影响性能。相反,当我们需要将整个片段存储在内存中时,应该使用它的兄弟 FragmentPagerAdapter。当我说整个片段保存在内存中时,这意味着它的实例不会被破坏并且会产生内存开销。因此,建议仅在 ViewPager 的片段数量较少时使用 FragmentPagerAdapter。如果片段是静态的会更好,因为它们不会有大量对象的实例将被存储。希望这可以消除 Android FragmentPagerAdapter 和 FragmentStatePagerAdapter 之间的区别。

尝试学习Google android Gallary应用示例,使用图像视图加载动画来打造出色的用户体验。

我希望这能解决你的堆增长问题。

致谢:FragmentPagerAdapter 与 FragmentStatePagerAdapter

于 2013-11-06T05:52:26.677 回答