首页 > 编程知识 正文

运行内存优化,进程与内存

时间:2023-05-05 01:52:34 阅读:245830 作者:1127

一.数据段

数据段中包含 bss与data两个节,其中data节用于保存初始化不为0的全局变量,而bss节用于初始化为0或者尚未初始化的全局变量。

为什么以0作为区分两个节?因为对于bss节来说,不需要在文件中保存变量的初值0,Loader只需要使用一个内容为0的page页面,因此该段并不占用文件的空间。但是对于data节来说,必须在文件中data节保存变量的初值,因此需要占用文件大小,当访问这些变量时会触发页故障,将文件中对应的初值加载到内存中,最终完成初始化。

以下分析bss与data对程序的影响。

bss.c

源代码:

#include <stdio.h>int bss[1024*1024]={0};int main(int argc,char *argv[]){bss[0]=1; printf("pid=%d,bss=%lxn",getpid(),bss);pause();return 0;}可执行文件大小:

-rwxr-xr-x 1 taisimin taisimin    6932 2011-12-07 15:37 bss
段分布:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x00120 0x00120 R   0x4
  INTERP         0x000154 0x08048154 0x08048154 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x08048000 0x08048000 0x0058c 0x0058c R E 0x1000
  LOAD           0x000f0c 0x08049f0c 0x08049f0c 0x00110 0x400134 RW  0x1000

虚拟内存使用:

08048000-08049000 r-xp 00000000 08:01 9836831    /home/taisimin/linux/optimization/process/bss
08049000-0804a000 r--p 00000000 08:01 9836831    /home/taisimin/linux/optimization/process/bss
0804a000-0804b000 rw-p 00001000 08:01 9836831    /home/taisimin/linux/optimization/process/bss
0804b000-0844b000 rw-p 00000000 00:00 0    【heap】

data.c 

 源码:

#include <stdio.h>int data[1024*1024]={2};int main(int argc,char *argv[]){data[0]=1; printf("pid=%d,data=%lx,n",getpid(),data);pause();return 0;}

可执行文件大小:

-rwxr-xr-x 1 taisimin taisimin 4201272 2011-12-07 15:38 data

段分布:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x00120 0x00120 R   0x4
  INTERP         0x000154 0x08048154 0x08048154 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x08048000 0x08048000 0x00590 0x00590 R E 0x1000
  LOAD           0x000f0c 0x08049f0c 0x08049f0c 0x400134 0x40013c RW  0x1000

虚拟内存使用:

08048000-08049000 r-xp 00000000 08:01 9836830    /home/taisimin/linux/optimization/process/data
08049000-0804a000 r--p 00000000 08:01 9836830    /home/taisimin/linux/optimization/process/data
0804a000-0844b000 rw-p 00001000 08:01 9836830    /home/taisimin/linux/optimization/process/data
40000000-4001c000 r-xp 00000000 08:01 7475104    /lib/i386-linux-gnu/ld-2.13.so

从以上数据可以看出:

1.bss的可执行文件大小较小。

2.bss中的的数据段正常,但是在stack段中多出4MB的消耗,而data中的数据段多出4MB的消耗,而没有stack段的消耗。这是因为loader对于bss节采用stack的内存空间进行映射,而对于data节直接采用文件的map方式进行内存映射。

二.变量所在内存区域

如下例所示:

var.c

#include <stdio.h>#define b 10#define c "123"int bss[10]={0};int data[10]={1};const int a=10;static int d;char *s1="hello,worldn";char s2[]="hellow,worldn";int main(int argc,char *argv[]){ return 0;}
使用nm -f sysv  var命令查看变量所在取悦

Symbols from var:

Name                  Value   Class        Type         Size     Line  Section
__bss_start         |0804a07c|   A  |            NOTYPE|        |     |*ABS*
__data_start        |0804a020|   D  |            NOTYPE|        |     |.data
_edata              |0804a07c|   A  |            NOTYPE|        |     |*ABS*
_end                |0804a0cc|   A  |            NOTYPE|        |     |*ABS*
_fini               |0804847c|   T  |              FUNC|        |     |.fini
_fp_hw              |08048498|   R  |            OBJECT|00000004|     |.rodata
_init               |080482bc|   T  |              FUNC|        |     |.init
_start              |08048320|   T  |              FUNC|        |     |.text
a                   |080484a0|   R  |            OBJECT|00000004|     |.rodata
bss                 |0804a0a0|   B  |            OBJECT|00000028|     |.bss
completed.6155      |0804a080|   b  |            OBJECT|00000001|     |.bss
d                   |0804a0c8|   b  |            OBJECT|00000004|     |.bss
data                |0804a040|   D  |            OBJECT|00000028|     |.data
data_start          |0804a020|   W  |            NOTYPE|        |     |.data
dtor_idx.6157       |0804a084|   b  |            OBJECT|00000004|     |.bss
frame_dummy         |080483b0|   t  |              FUNC|        |     |.text
main                |080483d4|   T  |              FUNC|0000000a|     |.text
s1                  |0804a068|   D  |            OBJECT|00000004|     |.data
s2                  |0804a06c|   D  |            OBJECT|0000000e|     |.data

可以看出const变量存放在rodata节中,即最终存放在text段中。

而s1,s2,data都存放在data节中,而bss存放在bss节中。

三.数据段优化

1.减少一个全局整形变量并不会只减少4B,因为Linux中采用页来分配内存。

2.优化data段带来的影响有限,特别是用户程序,但是对于动态库的数据段做优化,其作用还是很明显,假如,一个动态库被100个进程所依赖执行,当所有进程都在执行时,内存中就会包含100份动态库的数据段,若能减少一个整形全局变量,理论上将会减少4B*100=400B的内存大小。

常用优化方法:

1. 使用nm -f sysv xx |grep -w .data (.bss)方式检查各个小节中的变量。

2.使用const方式来修饰只读的全局变量,从而将其转移到代码段中,利用代码段的共享内存方式来减少内存使用

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。