|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1、内核分配物理内存的最小单位为一个物理页面,一个物理页面为4kb。无论虚拟内存分配了多少字节,比如malloc(400),内核仍然分配4kb物理内存页面。
& C* H, |: J8 O1 f2、malloc语句执行时,只是给进程分配了虚拟内存,虚拟内存此时不占用物理内存。当使用此处内存时,比如变量赋值*p = ??或mEMCpy或strcpy时,内核会产生一个页故障,从而为进程分配一个物理页面。9 B) P( ?% G4 z! B' m2 V. G( t
3、进程状态可以在/proc中根据pid值找到进程的目录。 目录中statm信息(cat statm)中的7个数,以页为单位。 从左至右依次为size:任务虚拟地址空间大小。 resident:应用程序正在使用的物理内存大小。 shared:共享页数。 trs:程序所拥有的可执行虚拟内存大小。 lrs:被映像到任务的虚拟内存空间的库的大小。 drs:程序数据段和用户态的栈的大小。 dt:脏页数量。
3 x+ z, c6 y2 z6 ~; k* j4、目录中maps信息(cat maps)中,表示进程使用的虚拟地址(栈,堆,代码等)。 内存使用权限信息r=读,w=写,x=执行,s=共享,p=私有。 r-xp通常表示代码段,只读,可执行。Rw-p通常表示数据段,可读写,不能执行。 rwxp通常表示栈段,读写,可执行。栈不仅可以保存数据,也可以保存代码。9 g) b! F3 |% ~9 Q& V& _" ]
5、32位操作系统中,进程虚拟内存为4g,分为两部分,内核空间(高1g),用户空间(低3g)。
% `6 D1 e$ U' I$ Z. V; Z- [5 q3 H6、堆段:每个进程有一个,不论是主进程、动态库还是不同的线程里申请的堆内存,都反映在进程的堆段。 栈段:每个线程有一个,如果进程中有多个线程,则包含多个栈段。 代码段:由于其只读,不会被修改,故其在整个系统中共享。比如说一个执行文件,在系统中同时存在多个进程,那么这些进程将共享其代码段所占用的内存。 数据段:由于它是可写的,其内容与其所在的进程高度相关,所以在程序运行时会为每个进程创建一个数据段副本,故每个进程有一个数据段。
9 U% U( q! b$ L/ U7、p = malloc(xxx); 分配给p的大小存放于*(p - 4)位置。; R2 D, G- Q7 a: o& V
8、readelf、size、strip命令的使用。Nm ???.out检查???.out执行文件的符号表。
4 g2 I7 B& A3 R' E( j0 ]; S9、检查当前内核配置的进程栈大小,使用ulimit -a命令查看stack size:。 如需设置栈大小,使用ulimit -s 16384,栈大小为16k。/ n( ~0 ~" x6 D9 T
10、线程栈空间未设置时,通常为2m。2m的栈空间略微显得太大。所以有必要修改线程栈空间大小。 设置方法为: pthread_attr_t tattr; pthread_attr_init(&tattr); pthread_attr_setstacksize(&tattr, --SIZE--); /* --SIZE-- 为设置的值,可以写8k等。*/ pthread_create(&tid, &tattr, start_routine, arg); /* 以tattr为属性创建线程 */
9 b5 v( A! v0 T4 Y* Y1 u11、进程启动前加载过多的动态库会影响进程启动速度。静态库编译进入进程时,其查找静态库中的函数时仅偏移计算一次即可调用静态库中的函数。 进程调用动态库中函数时,进程将处理权交给linker,由于linker也不知道调用的函数是在哪个动态库,所以它将在整个执行文件和动态库的范围内查找。这种查找是符号表字符串的查找比较,效率较为低下,间接影响了进程的启动速度或执行速度。
# J, x0 w8 O9 G$ x* m, @; H# R12、善用查表法(数组)优化查找效率。
/ I# P- b9 E! D) O13、对于if中的逻辑连接运算符,尽量将计算速度最快的条件放在运算符左边。例如if((b == 0) || (TURE == func(a, b)))。同理,概率大的条件,也尽量放在左边。* N: r3 R. N5 S1 u
14、利用现代cpu乱序执行的特点,将访问内存的语句置入代码块前端,其后代码为访问cache,所以可以在cpu等待访问内存的时间利用在计算访问cache的语句,达到看似无缝内存访问时延的指令执行。
( D/ F2 P ^7 u6 E. q9 Y+ j O$ {. u5 p |
|