我的进阶曲线之六

用更少的内存来运行Android


简介
android现在可以运行在只有512M RAM的设备上了。本文就是用来帮助OEM厂商进行配置和优化,使得Android4.4运行在低内存设备上。
部分优化措施因为比较通用,也可以在前几个android版本上部署。




Android 4.4 平台优化策略


优化内存管理
检查内核节省内存的相关配置,如KSM(Kernel Same-page Merging)配置,ZRAM(压缩内存区)配置等。
结束掉那些缓存过大并且即将换出的进程。
禁止占用太多资源的服务在后台运行(当然,还是要保证luncher能正常运行的)
结束掉那些在空闲状态占用大量资源的进程(即使是一些平常被认为不可随便结束的进程,如输入法管理IME)
序列化后台加载的服务
调整那些小内存设备的内存使用,更加苛刻的oom调整机制,更小的图形缓存等。


缩减系统所需内存
对system_server和SystemUI processes进行裁剪(可省出来几MBs内存)
dalvik虚拟机预加载dex缓存(可省出来几MBs内存)
dalvik虚拟机关闭jit。(每个进程差不多省出来1.5MB )
缩减每个进程的字库缓存。
用更轻量级的 HashMap/HashSet 来替换之前framework中使用的ArrayMap/ArraySet。


关于进程状态
android4.4 添加了一个新的开发者选项,用来显示内存状态和应用的内存使用情况,按照使用频率和占用内存的量来排名。


API
新增加了一个api: ActivityManager.isLowRamDevice()
用来让应用开发者检测是否运行在低内存设备上,那时候就要关闭一些耗内存的属性了。


内存监视
新的内存监视HAL层实现了对图形内存使用情况跟踪,在meminfo的dump信息有了更多的内容,会有一个简单内存使用统计呈现,例如缓存进程的地址空间的空闲内存,有这个的话,就不至于做一些不合理的优化。


编译时候的配置
开启小内存标志位
上文中我们介绍过新API:ActivityManager.isLowRamDevice(),
对于 512MB 内存的设备,如果在makefile中做了如下系统属性配置:
PRODUCT_PROPERTY_OVERRIDES += ro.config.low_ram=true
那么,就意味着标记了小内存设备,该API此时就会返回TRUE。


关闭JIT
整个系统所需的JIT内存空间取决于正在运行的应用数量和这些应用的运行时的执行路径。JIT会初始化一个尽可能大的翻译缓冲区阈值以满足其需求。一般在系统运行期间,JIT消耗3M-6M左右的空间。


规模比较大的应用倾向于迅速地消耗完指令缓存区(一般为1M),平均地看,一个应用JIT的指令缓存使用在100K-200K之间。减小最大阈值有助于省出内存,不过,如果这个阈值设定得太小,也会导致JIT运行产生抖动。
如果在一个小内存设备上,我们建议完全关闭掉JIT功能。
可在MAKEFILE中添加如下配置实现:
PRODUCT_PROPERTY_OVERRIDES += dalvik.vm.jit.codecachesize=0


Launcher的配置
请确认默认墙纸不要使用动态墙纸。小内存设备不会预装动态墙纸。




KERNEL配置
1. 调整kernel/ActivityManager 内存配置参数,对 “直接回收”的边界值做合理设定。
当有进程想要申请内存(不管是直接申请还是缺页机制),可KERNEL已经用光了所有可用内存的时候,就会触发直接回收机制。
这就要求KERNEL在释放一些内存页的时候,阻塞申请请求。此时一般会释放缓存并同步到磁盘文件去,或者等lowmemorykiller来杀掉某个进程。这就可能对某些线程(包括UI线程)产生一些额外的I/O开销。


为了避免直接回收,KERNEL有一个触发kswapd或者后台回收的边界值。kswapd是一个守护进程,用来尽量释放一些页面,使得下次有用户进程申请的时候能迅速地获得。


默认的触发直接回收的边界值非常小,在一个内存2G的设备上差不多2M左右,512M的只有636KB。并且后台回收中KERNEL也只能回收几MB而已。这就意味着任何紧急申请多于1M的进程都会触发直接回收。


在android 4.3 kernel 上打上了一个调节kbyte释放的补丁,支持一种新的KERNEL调整。这个补丁(Cherry-picking)允许ActivityManager 通知KERNEL尽量保留3个全屏32位bpp的可用缓存空间。


这个边界值可以通过framework里面的config.xml来配置。


2. 调整LowMemoryKiller的触发边界值。
3. 采用KSM (Kernel samepage merging)机制。
4. 交换内存到zRAM块。

5. 对CMA(Contiguous Memory Allocation)区域采用Ion机制



ANR 三种情况


1 键盘输入
KeyDispatchTimeout(5 seconds) --主要类型按键或触摸事件在特定时间内无响应


staticfinal int KEY_DISPATCHING_TIMEOUT = 5*1000


2 接收者者处理超时
 BroadcastTimeout(10 seconds) --BroadcastReceiver在特定时间内无法处理完成


3 服务
ServiceTimeout(20 seconds) --小概率类型 Service在特定的时间内无法处理完成






UI线程及Android的单线程模型原则


  当应用启动,系统会创建一个主线程(main thread)。


  这个主线程负责向UI组件分发事件(包括绘制事件),也是在这个主线程里,你的应用和Android的UI组件(components from the Android UI toolkit (components from the android.widget and android.view packages))发生交互。


  所以main thread也叫UI thread也即UI线程。
 
  系统不会为每个组件单独创建线程,在同一个进程里的UI组件都会在UI线程里实例化,系统对每一个组件的调用都从UI线程分发出去。


  结果就是,响应系统回调的方法(比如响应用户动作的onKeyDown()和各种生命周期回调)永远都是在UI线程里运行。


原则:


  1.不要阻塞UI线程。


  2.不要在UI线程之外访问Android UI toolkit(主要是这两个包中的组件:android.widget and android.view)。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当涉及到 MATLAB 的图形绘制时,以下是一些进阶技巧和建议: 1. 选择合适的绘图函数:MATLAB 提供了许多绘图函数,如 `plot`、`scatter`、`bar`、`histogram` 等。了解每个函数的特点和应用场景,选择合适的函数来绘制你所需的图形。 2. 自定义图形外观:除了基本的绘图函数,MATLAB 还提供了许多选项来自定义图形的外观。例如,你可以设置线条颜色、线型、线宽、标记符号、坐标轴范围等。通过使用这些选项,你可以使图形更具个性化。 3. 组合多个图形:有时候你可能需要在同一张图上绘制多个曲线或图形。你可以使用 `hold on` 命令来保持当前图形,并在后续的绘图命令中添加新的曲线。使用 `legend` 函数可以为每个曲线添加图例。 4. 使用子图:如果你希望将多个图形放置在同一窗口中,并对它们进行比较或共享坐标轴,可以使用子图。通过 `subplot` 函数,你可以将窗口分割为不同的区域,并在每个区域中绘制不同的图形。 5. 使用图形对象:MATLAB 还支持图形对象的概念,例如 `figure`、`axes`、`line` 等。通过使用图形对象,你可以更精确地控制图形的属性和行为。这对于创建复杂的图形以及动画效果非常有用。 6. 保存图形:一旦你满意了绘制的图形,你可以使用 `saveas` 或 `print` 函数将图形保存为文件。MATLAB 支持多种文件格式,如 PNG、JPEG、PDF 等。 这些是 MATLAB 图形绘制的一些进阶技巧和建议。希望对你有所帮助!如果你有具体的问题或需要更详细的解释,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值