Date
Jul. 14th, 2024
 
2024年 6月 9日

Post: iOS 入门 002: 内存空间地址

iOS 入门 002: 内存空间地址

Published 12:04 Apr 02, 2012.

Created by @ezra. Categorized in #Programming, and tagged as #iOS.

Source format: Markdown

Table of Content

内存空间地址

基本概念

  • 程序员直接接触的内存地址为 虚拟内存地址,而非物理内存地址

  • 以32位系统为例,每个进程都对应4GB虚拟内存地址空间,其中0-3GB为 用户层 ,3-4GB为 内核层

  • 程序员可以直接操用户层,用户层无法直接操作内核层

  • 虚拟内存地址本身不对应任何物理内存或硬盘文件,因此不能存储数据,必须映射到物理内存或硬盘文件,也即分配内存

  • 内存管理的单位是字节,内存映射的基本单位是内存页,一次映射必须是内存页的整数倍

  • getpagesize()可以获取当前系统内存页一页的大小,通常为4096字节

  • 如果不映射而直接使用虚拟内存地址,会引发段错误

  • 对内存进行没有权限的操作也会引发段错误

内存空间区域划分

  • 堆区

    • newdeletemalloc()free()等都在堆区分配和回收内存,堆区内存由程序员手动管理
  • 栈区

    • 存放局部变量、函数形参,由系统自动管理
  • BSS段

    • 存放未初始化的全局变量,在 main() 之前会自动清零
  • 全局区(静态区)

    • 存放已初始化的全局变量、静态变量
  • 只读常量区

    • 存放常量值、const修饰的全局变量,只读,例如C语言字符串的字面值 "abc"
  • 代码区

    • 存放代码,只读

    • 函数指针的值就是函数在代码区的地址

申请内存后系统的响应

    • 只要栈的剩余空间⼤大于所申请空间,系统将为程序提供内存,否则将报异常提⽰栈溢出
    • 操作系统有⼀一个记录空闲内存地址的链表

    • 当系统收到程序的申请时,会遍历该链表,寻找第⼀一个空间⼤大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序

    • 由于找到的堆结点的⼤大⼩小不⼀定正好等于申请的⼤大⼩小 系统会⾃自动的将多余的那部分重新放⼊入空闲链表中

申请大小的限制

    • 栈是向低地址扩展的数据结构是⼀一块连续的内存的区域,栈顶的地址和栈的最⼤大容量是系统预先规定好的
    • 堆是向⾼高地址扩展的数据结构,是不连续的内存区域,这是由于系统是用链表来存储的空闲内存地址的,⾃自然是不连续的,⽽链表的遍历⽅向是由低地址向⾼地址

    • 堆的⼤大⼩小受限于计算机系统中有效的虚拟内存

  • 由此可见,堆获得的空间⽐比较灵活,也⽐比较⼤大

申请效率

    • 由系统自动分配,速度较快
    • 速度较慢,容易产生内存碎片,但是使用方便

malloc()/free()

  • malloc()一次会映射33个内存页,如果一次申请超过33个内存页,则会映射比33个多一点的内存页(系统不同,值不同)

  • malloc()分配内存时,会额外存储一些附加"信息,如分配内存的大小值等,因此其分配的内存地址是不连续的

  • free()只释放虚拟内存地址,将已使用的内存地址标记为未使用,未必会解除映射(最后33个内存页不能接触映射)

  • 使用malloc()分配内存时不要越界使用,否则会损毁附加数据,影响free()

sbrk()/brk()

sbrk.c

#include <stdio.h>
#include <unistd.h>
int main(){
    void *p0 = sbkr(1);//分配1字节内存
    void *p1 = sbrk(4);//再分配4字节内存
    sbkr(0);//取当前位置
    sbrk(-1)://释放1字节
    sbrk(4);//全部释放
    return 0;
}

brk.c

#include <stdio.h>
#include <unistd.h>
int main(){
    void *p0 = sbrk(0);
    brk(p0 + 1);//分配1字节内存
    brk(p0 + 4);//再分配3字节内存,共4字节
    void *p1 = sbrk(0);
    brk(4);//分配4字节
    void *p2 = sbrk(0);
    brk(8);//分配8字节
    void *p3 = sbrk(0);
    brk(p3);//释放p3
    brk(p0);//全部释放
    return 0;
}
Pinned Message
HOTODOGO
I'm looking for a SOFTWARE PROJECT DIRECTOR / SOFTWARE R&D DIRECTOR position in a fresh and dynamic company. I would like to gain the right experience and extend my skills while working in great teams and big projects.
Feel free to contact me.
For more information, please view online résumé or download PDF
本人正在寻求任职 软件项目经理 / 软件技术经理 岗位的机会, 希望加⼊某个新鲜⽽充满活⼒的公司。
如有意向请随时 与我联系
更多信息请 查阅在线简历下载 PDF