操作系统利用体系结构提供的VA到PA的转换机制实现虚拟内存管理,下面可以进一步来理解虚拟内存管理:,今天小编就来聊一聊关于linux下c程序释放内存?接下来我们就一起去研究一下吧!
linux下c程序释放内存
操作系统利用体系结构提供的VA到PA的转换机制实现虚拟内存管理,下面可以进一步来理解虚拟内存管理:
# ps
PID USER TIME COMMAND
1 root 0:14 {linuxrc} init
2 root 0:00 [kthreadd]
3 root 0:00 [ksoftirqd/0]
4 root 0:00 [kworker/0:0]
5 root 0:00 [kworker/0:0H]
7 root 0:47 [rcu_preempt]
8 root 0:00 [rcu_sched]
9 root 0:00 [rcu_bh]
10 root 0:00 [migration/0]
11 root 0:00 [watchdog/0]
12 root 0:00 [watchdog/1]
13 root 0:00 [migration/1]
14 root 0:00 [ksoftirqd/1]
16 root 0:00 [kworker/1:0H]
17 root 0:00 [kdevtmpfs]
983 root 0:02 mc_server
用ps命令查看当前终端下的进程,得知mc_server进程的id是983,然后使用car /proc/983/maps 命令查看它的虚拟地址空间。/proc 目录中的文件并不是真正的磁盘文件,而是由内核虚拟出来的文件系统,当前系统中运行的每个进程在/proc 文件都有一个子目录,目录名就是进程的id,查看目录下的文件可以得到该进程的相关信息。
# cat /proc/983/maps
00400000-00401000 r-xp 00000000 1f:05 384 /usr/bin/mc_server
00410000-00411000 rw-p 00000000 1f:05 384 /usr/bin/mc_server
16ce7000-17103000 rw-p 00000000 00:00 0 [heap]
7f8c7cb000-7f8c7d1000 r-xp 00000000 1f:05 208 /lib/librt-2.23.so
7f8c7d1000-7f8c7e0000 ---p 00006000 1f:05 208 /lib/librt-2.23.so
7f8c7e0000-7f8c7e1000 r--p 00005000 1f:05 208 /lib/librt-2.23.so
7f8c7e1000-7f8c7e2000 rw-p 00006000 1f:05 208 /lib/librt-2.23.so
7f8c7e2000-7f8c90d000 r-xp 00000000 1f:05 187 /lib/libc-2.23.so
7f8c90d000-7f8c91c000 ---p 0012b000 1f:05 187 /lib/libc-2.23.so
7f8c91c000-7f8c920000 r--p 0012a000 1f:05 187 /lib/libc-2.23.so
7f8c920000-7f8c922000 rw-p 0012e000 1f:05 187 /lib/libc-2.23.so
7f8c922000-7f8c926000 rw-p 00000000 00:00 0
7f8c926000-7f8c93a000 r-xp 00000000 1f:05 463 /usr/lib/libcncrDriver.so
7f8c93a000-7f8c949000 ---p 00014000 1f:05 463 /usr/lib/libcncrDriver.so
7f8c949000-7f8c94a000 rw-p 00013000 1f:05 463 /usr/lib/libcncrDriver.so
7f8c94a000-7f8cb86000 rw-p 00000000 00:00 0
7f8cb86000-7f8cb95000 r-xp 00000000 1f:05 494 /usr/lib/libibcUtilsMc.so
7f8cb95000-7f8cba5000 ---p 0000f000 1f:05 494 /usr/lib/libibcUtilsMc.so
7f8cba5000-7f8cba8000 rw-p 0000f000 1f:05 494 /usr/lib/libibcUtilsMc.so
7f8cba8000-7f8cbaa000 rw-p 00000000 00:00 0
7f8cbaa000-7f8cbc0000 r-xp 00000000 1f:05 204 /lib/libpthread-2.23.so
7f8cbc0000-7f8cbd0000 ---p 00016000 1f:05 204 /lib/libpthread-2.23.so
7f8cbd0000-7f8cbd1000 r--p 00016000 1f:05 204 /lib/libpthread-2.23.so
7f8cbd1000-7f8cbd2000 rw-p 00017000 1f:05 204 /lib/libpthread-2.23.so
7f8cbd2000-7f8cbd6000 rw-p 00000000 00:00 0
7f8cbd6000-7f8cbe0000 r-xp 00000000 1f:05 462 /usr/lib/libboardConfigOPMc.so
7f8cbe0000-7f8cbef000 ---p 0000a000 1f:05 462 /usr/lib/libboardConfigOPMc.so
7f8cbef000-7f8cbf0000 rw-p 00009000 1f:05 462 /usr/lib/libboardConfigOPMc.so
7f8cbf0000-7f8cc18000 rw-p 00000000 00:00 0
7f8cc18000-7f8cc35000 r-xp 00000000 1f:05 179 /lib/ld-2.23.so
7f8cc3e000-7f8cc42000 rw-p 00000000 00:00 0
7f8cc42000-7f8cc43000 r--p 00000000 00:00 0 [vvar]
7f8cc43000-7f8cc44000 r-xp 00000000 00:00 0 [vdso]
7f8cc44000-7f8cc45000 r--p 0001c000 1f:05 179 /lib/ld-2.23.so
7f8cc45000-7f8cc47000 rw-p 0001d000 1f:05 179 /lib/ld-2.23.so
7fdba5c000-7fdba86000 rw-p 00000000 00:00 0 [stack]
x86 平台的虚拟地址空间是0x0000 0000 0xffff ffff, 大致上前3GB(0x0000 0000 00xbfff ffff)是用户空间,后1GB(0xC000 0000 ~ 0xffff ffff)是内核空间。
0x00400000-0x00401000地址段,访问权限是 r-x, 表示Text Segment, 包含.text段,.rodata段,.plt段等。
0x00410000-0x00411000地址段,访问权限为r-w, 表示Data Segment,包含.data段,.bss段等。
0x16ce7000-0x17103000不是从磁盘文件加载到内存的,这段空间称为堆(Heap), malloc函数动态分配内存是在这里分配的。
从0x7f8c7cb000开始是共享库的映射空间,每个共享库也分为几个Segment,每个Segment有不同的访问权限。从堆空间的结束地址0x17103000到共享库映射空间的起始地址0x16ce7000之间有很大的地址空洞,在地址分配内存时堆空间是可以向高地址增长的。堆空间的地址上限称为Break, 堆空间要向高地址增长就要抬高Break, 映射新的虚拟内存空间到物理内存,这是通过系统调用brk实现的。malloc函数也是调用break向内核请求分配内存的。
0x7fdba5c000-0x7fdba86000是栈空间,其中高地址的部分保存着进程的环境变量和命令行参数,低地址的部分保存函数栈帧,栈空间是向低地址增长的,但显然没有堆空间那么大的可供增长的余地,因为实际的应用程序动态分配大量的并不少见,但是函数调用有很多局部变量的非常少见。栈空间是可能用尽的,并且比堆空间更容易用尽,用尽栈空间最终导致段错误。
,