Android logCat 里面一直打印GC_EXPLICIT ,界面有反应迟钝的现象

转载 2013年12月03日 14:01:56

转载http://segmentfault.com/q/1010000000141620



我在一个Activity中有一个大的ListView(ListView中的每个Item填充的东西比较多,还有大量图片),出现的现象就是滑动不流畅,操作出现反应迟延,在LogCat中频繁的打印GC_EXPLICIT,通过网上了解,应该是内错的问题,之所以反应迟钝,滑动不流畅是因为要等待内存释放,重新申请新的内存,但是不知道怎么解决。请有经验的高手指点。
完整的几条logcat:

11-17 10:19:45.257: D/dalvikvm(22511): GC_EXPLICIT freed 14K, 52% free 3715K/7687K, external 7372K/9177K, paused 25ms
11-17 10:19:45.414: D/dalvikvm(22511): GC_EXPLICIT freed 14K, 52% free 3715K/7687K, external 7372K/9177K, paused 26ms
11-17 10:19:45.722: D/dalvikvm(22511): GC_EXPLICIT freed 39K, 52% free 3717K/7687K, external 7372K/9177K, paused 25ms
11-17 10:19:45.875: D/dalvikvm(22511): GC_EXPLICIT freed 13K, 52% free 3717K/7687K, external 7372K/9177K, paused 25ms
 

已经大半年不碰Android了,以下是一些记忆中的经验,供参考。

首先确实是内存问题,这些都是DalvikVM的GC日志,格式如下:

[GC原因] [释放了多少VM内存], [VM堆内存统计], [外部内存统计], [VM暂停时间]

其中[原因]的内容可以参考Android源码中/dalvik/vm/alloc/Heap.h中enum GcReason的定义:

typedef enum {
    /* Not enough space for an "ordinary" Object to be allocated. */
    GC_FOR_MALLOC,
    /* Automatic GC triggered by exceeding a heap occupancy threshold. */
    GC_CONCURRENT,
    /* Explicit GC via Runtime.gc(), VMRuntime.gc(), or SIGUSR1. */
    GC_EXPLICIT,
    /* GC to try to reduce heap footprint to allow more non-GC'ed memory. */
    GC_EXTERNAL_ALLOC,
    /* GC to dump heap contents to a file, only used under WITH_HPROF */
    GC_HPROF_DUMP_HEAP
} GcReason;

你日志中的GC_EXPLICIT就是说有调用过Runtime.gc()或VMRuntime.gc()(可能是SDK调的)。然后[VM暂停时间]是“hold the whole world”,就是所有东西都停止,会非常影响体验,就是造成你觉得操作卡顿的主要原因。

然后是解决方案。在ListView/GridView之类的东西里面展现图片很容易就会遇上内存问题,说白了就是内存里的图片太大内存不足,好点的引发GC卡顿,差点的就直接OOM了。所以有几个解决思路:

1. 减少图片文件大小
调整图片大小或是降低图片色彩值或是修改图片格式都可以有效降低图片文件大小。例如色彩较丰富的图片jpg就比png要小一些,能做点九的尽量点九,减少色彩值数量可以显著降低png图片大小,特别是如果可以控制在256种颜色之内就可以启动png的色彩索引方案,加大jpg的压缩比例也可以让图片小很多。此方案的缺点则是图片必须是由我们自己处理的,例如静态资源或是从自己服务器获取的图,可以做预先处理。

2. 减少图片在内存中的大小
图片文件有多大并不代表它在内存里就占用多少空间,因为我们可以在图片加载过程中对其数据进行一些修改以达到减少在内存中占用的效果。一般来说有两种办法:
1) 动态修改图片色值,例如从8888改为565这种,以前我们用过对大图片非常有效。
2) 先用仅读取图片的bounds,然后依此缩小图片(代码网上很多),销毁掉大图仅使用小图,再做显示处理,也是一个常用方法。

3. 更好的利用内存
首先要理解Android中bitmap用的是native的内存,你可以理解为是C用的那段内存,与java用的不在一起。Android从3.2版本以后加强了这块的管理,使得native内存会随着JVM的GC一起回收,所以会大大减少这块的问题(3.2之前的版本也会回收,但因为与Java GC不同步所以一般回收不及时就会暴内存溢出,因此需要开发者手工调用recycle())

然后遵循一条法则:“永远只存放要显示的图片在内存中”,也就是说只有用户看得见的图片才在内存里,看不见的就销毁(recycle()),需要时再重新加载。这点与ListView的滑动窗口是一个道理。

要做到这些,recycle()总是需要自己写逻辑(对于3.2之前的版本),但留在JVM内存的那部分可以交给系统来管理,以前较为常用的建议是SoftReference和WeakReference,现在一般建议使用Android自带的缓存类LruCache或LruDiskCache,它会自动按照LRU算法销毁队列尾部的元素(最不常用),而非看GC心情,使用参见 Android Developer - Caching Bitmaps

另外楼主也应该尽量减少View的个数,能合并的尽量合并,尽量少使用重量级的View(可以查看View的源码由其成员变量组成来确定是轻是重)。如果以上这些都做了依然有大量的GC,建议在业务可接受的范围内与产品讨论简化界面。


Android logCat 里面一直打印GC_EXPLICIT ,界面有反应迟钝的现象。

我在一个Activity中有一个大的ListView(ListView中的每个Item填充的东西比较多,还有大量图片),出现的现象就是滑动不流畅,操作出现反应迟延,在LogCat中频繁的打印GC_EX...
  • caihongshijie6
  • caihongshijie6
  • 2014年09月30日 20:31
  • 1935

Android 在屏幕上打印LOG

Android开发中需要迅速定位问题,在Android 屏幕上打印LOG,是一个很好的通道 基本的思路:启动LogService读取指定log,使用WindowManager展示到屏幕上 直接上代...
  • lushitianxia
  • lushitianxia
  • 2016年05月10日 10:32
  • 1964

鼠标飘反应迟钝怎么办 如何解决?

相信有不少网友在玩游戏时出现过“鼠标飘”的情况,就是游戏控制物体与鼠标操控间有明显的延迟,比如玩FPS游戏时,瞄准镜头总是慢一拍,这种时候 就很想砸鼠标有木有?!因此就牵连出一个问题,鼠标飘怎么办?今...
  • pizi0475
  • pizi0475
  • 2012年10月17日 22:00
  • 758

诺基亚N9手机升级后PR1.3后反应迟钝、发热、耗电快的问题

(本文所述方法适合大陆地区,中文N9系统) 2012年7月份,诺基亚发布了N9手机系统的最新版本PR1.3(感动中!诺基亚工程师的敬业精神还是值得尊敬的,在操作系统为王的移动互联网时代,诺基亚如...
  • hugewave
  • hugewave
  • 2012年07月22日 11:59
  • 4395

苹果傲慢失荆州:反应迟钝导致数十万Mac中病毒

国外媒体今天撰文称,由于苹果的反应迟钝,导致大量Mac OS X用户被Flashback病毒感染。虽然很多人认为苹果的举动难以理解,但这其实完全符合该公司一贯的“控制癖”,在接到甲骨文的预警后,它并没...
  • cometwo
  • cometwo
  • 2013年01月04日 21:36
  • 1114

电脑反应迟钝怎么办

  • 2014年09月08日 16:42
  • 20KB
  • 下载

三星Galaxy EK-GC 100 android智能照相机的logcat

  • 2016年02月24日 17:44
  • 14KB
  • 下载

phonegap监听backbutton点击事件后,其他页面点击回退键出现无反应现象

phonegap版本: 4.2.0 问题描述: 比如我们有三个页面,分别是main.html,page1.html,page2.html。我们有这样的需求:当在main.html页面点击回退键时要...
  • TowardsYoung
  • TowardsYoung
  • 2015年03月16日 17:24
  • 2048

AOP 面向切面编程

AOP 面向切面编程 1.使用场景还原 当我们打开京东 app 进入首页,如果当前是没有网络的状态,里面的按钮点击是没有反应的。只有当我们打开网络的情况下,点击按钮才能跳转页面.按照我们一般人写代...
  • hunter_cg
  • hunter_cg
  • 2017年11月30日 18:41
  • 48

android adb命令打印logcat日志 到指定目录

一 配置adb环境: 1.      找到sdk的adb.exe目录:D:\AndroidSoft\Eclipses_64\android-sdk\platform-tools 2.      A...
  • a2241076850
  • a2241076850
  • 2017年10月26日 17:30
  • 186
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android logCat 里面一直打印GC_EXPLICIT ,界面有反应迟钝的现象
举报原因:
原因补充:

(最多只允许输入30个字)