内存问题

首先,总内存量需要被各种CPU划出部分使用,剩余才是系统可用内存。这个概念差不多相当于电脑上的共享显存,系统对划走的内存是没有管理能力的,因此在/proc/meminfo中找不到这部分内存。这部分内存既不能优化也不能使用,因此其实是不可使用内存。厂家出厂内存(标称内存)和可使用内存一定存在差,具体多少看各种机型。htcg2是288m标称191m可用,p81hd是512m标称288m可用。

可用内存是linux kernel能管理的内存,这部分再会被划出一些供系统使用/服务使用/常驻程序使用。这部分是可以优化的,少编译一些ko模块,少开一些服务,少一些常驻程序,内存就会节约一点。

最后,剩下来的内存才是程序实际能用的量,htcg2和p81hd都在100-150M上下。不过程序退出时,内存并不交还给系统。而是当系统内存不足时(memory threshold,通常24m),由系统分析目前内存中,使用频率最少的一块,然后去释放这个内存。通常而言,你在系统中开了三五个程序,然后按Home退出到桌面,再进入时程序还处于退出当时所处的状态,这就是因为还在内存中没有释放的缘故。而当你开的程序比较多,例如十多个程序,也是由Home退出到桌面,再进入最老的一个程序时,程序已经处于初始的状态。这就是因为内存不足,系统帮你杀了这个程序的缘故。如果用Back键退出,程序会直接关闭,内存释放,这个无关系统是否有空余内存。

所以,对android而言,内存只代表两件事情。一个是所能运行的最大的程序。如果总内存不足,一些一次性需要内存比较大的程序就会无法运行,特征是一运行就退出,系统没有提示错误。另一个是同时在内存中不关闭的程序的数量。内存越大,在机器中就可以保持越多的程序处于打开状态。对于新打开程序(此时内存请求较多),或者程序突然申请大量内存,系统就开始释放其他程序,此时系统会稍慢。但是在考虑是否需要使用内存优化软件的时候,不妨这么想。内存优化软件运行的时间,一般比直接kill进程还长呢。

如果觉得自己内存不足,想要优化的话,需要非常注意系统中的服务。系统中一般会有很多服务在运行,很多都是消息通知类的,例如fackbook的新消息,twitter的新消息通知,google plus的消息通知,还有微信,等等。这些消息通知每个大概都是5-10m内存不等。有的时候,如果你不需要消息通知,关闭消息通知可以有效关闭服务,例如ubersocial的消息通知是可以关闭的,而google plus和facebook就没有这个选项。如果你觉得这两个的消息浪费内存,那只有卸载他们。至于微信,你可以使用程序中的退出功能关闭微信。一旦关闭,通知服务会自动关闭。

内核模块问题

一般而言,系统内核会编译进很多东西,但是也有不少东西是不编译进去的。这些可以动态载入的东西,就叫内核模块。对android而言,其实普通用户没必要在意到底机器内的某个模块是模块形式还是编译进入了内核,所以下面统称内核功能。无论是模块还是内核形态,只要能用,就称这个功能打开。

内核常用的几个功能有,cifs,tun。

cifs是用于smb挂载的内核模块,如果内核中有这个东西,你就可以把你的某个samba服务器当作机器本地的sd卡来用。samba服务器可能听起来很陌生,不过windows文件共享就是一种samba服务器。也就是说,拥有cifs,可以将windows下面的文件当作机器的本地sd卡来随意读写。这对于家庭内使用android是个很方便的事情。

不过cifs现在用的比较少,因为ES文件管理器有个功能,可以把远程文件转换成一个http流。视频之类可以以http流模式工作的文件就可以直接远程打开。

tun是一个很重要的内核模块,因为openvpn/anyvpn都需要使用这个东西来工作。没有tun模块,这两个程序将无法工作。

存储形态问题

任何一个android设备都一定会搭配一块存储。这块存储会被切分为多个区域,模拟成一个硬盘的多个分区来使用。我们来看一个内核的启动参数,以下数据来自我的P81HD。

console=ttyS1,115200n8n androidboot.console=ttyS1 init=/init initrd=0x62000000,0x800000 mtdparts=rk29xxnand:0x00002000@0x00002000(misc),0x00004000@0x00004000(kernel),0x00008000@0x00008000(boot),0x00008000@0x00010000(recovery),0x00078000@0x00018000(backup),0x0003a000@0x00090000(cache),0x00100000@0x000ca000(userdata),0x00002000@0x001ca000(kpanic),0x00080000@0x001cc000(system),-@0x0024c000(user) bootver=2011-08-05\#2.06 firmware\_ver=0.2.3

能明显看出,存储使用的是nand,编译是针对rk29xx的,所以模块叫做rk29xxnand。mtdparts里面规定了rk29xxnand的分区特性,每组三个数据,第一个是大小,第二个是起始位置,第三个是分区名。其中userdata实际大小256m,表上面写的是1m,因此1相当于256字节。下面可以再看一下mount表。

/dev/block/mtdblock8 on /system type ext3 (ro,noatime,nodiratime,data=ordered)
/dev/block/mtdblock6 on /data type ext3 (rw,nosuid,nodev,noatime,nodiratime,errors=continue,data=ordered)
/dev/block/mtdblock5 on /cache type ext3 (rw,nosuid,nodev,noatime,nodiratime,errors=continue,data=ordered)

可以看出存储编号是从0开始的。分区后,存储的内容即是以ext3格式存储。

系统组织问题

android的系统组织很有意思,并不是按照FHS来组织的,却部分兼容于FHS。

android最基础的一个分区是system,这个分区被mount到/system。/etc一般都是直接link到了/system/etc下面,由此可见这个分区的重要性。这个分区一般存放所有系统内置的,不能更改的程序和数据。例如系统的内置app,framework,java基础库,so库,系统程序,等等。一般的刷机包里面,都是以zip格式打包了system的新内容。一旦这个内容被替换,系统就有了新特性。一般一个system的大小是200m-500m,不会全部用满,会留出一些方便后续的升级改造。

data里面是系统内置的存储区域,这个区域常常被误叫为手机内存。实际上内存是ram,这块类似于rom。一般是500m上下,程序安装后就是装到了这个,包括数据也保存在这里。如果这个区域不足,系统就不能安装新程序。因此有些人想出了app2sd的把戏,说白了,就是通过bind,把sd卡上的一块区域映射到这个区域的某个目录下,使得某个app的数据可以存储到sd卡上。当然,这个能够转移过去的只限于数据,代码好像是不能转移的。而且,mount需要时间,sd的读取一般也比rom更加慢和麻烦。因此app2sd后,系统启动速度会变慢,程序运行也会变慢。

一个更好的扩充data的方案(当然,也更危险)是,通过修改刷机包,将上面kernel参数改变掉,并且重新分区nand。这样,data区的大小可以增加到1g左右,而user区的大小会减小相应的量。这样处理后,手机上可以安装更多的程序,而且没有什么后遗症。

cache里面是缓存,这个直观感受并不多,也很少用满,所以不解释。程序里面一般会列出,使用多少缓存,就是指的这个区域。

权限管理问题

android手机的权限很有意思。和macbook有点类似,但不完全相同。

android手机的每个程序,都有一个权限和他相关。规定的事情可以做,不规定的不能做。估计是给程序新建了一个身份,可以做的事情做成组,然后对身份加组。但是其中,有一类特殊的权限,正常情况下是任何程序都无法申请的,即是sid权限。学过linux的应当知道,就是可以切换成root身份的权限。

android的root,基本方法都是通过某种方法将/system改成可读写,然后用自己做的su替换/system/bin/su文件。自己做的程序,会以一些方法验证某个程序是否具有su的权限(一般是弹出对话框确认),然后让他们可以拥有最高权限。可以su的程序,他们的权限表就没有意义了。

adhoc问题

adhoc是一种常见的wifi形态,特征是没有一个ap(常见的路由器即是一种ap),全部由普通的客户端电脑来进行网络连接。

android的wpa_supplicant文件做过一些修改,过滤了adhoc网络的essid。所以,如果你使用adhoc模式共享了网络,你的android设备将无法使用。

但是android是可以做出adhoc的。这是很悖论的一个事情,android自己做出的网络分享,另一台android是无法使用的。