基本概念
关于内存方面的知识点
- 关于内存分配方式,基本上都知道内存分为几大区域:** 栈、堆、全局区(静态区)、常量区、代码区** 。栈和堆,这个两个对于我们来说是相当的熟悉,基本都很清楚了,但是这里还是bibi下,就当是重新学习下。
栈(stack):由编译器自动分配和释放缓存数据的一个内存块,存放函数的参数值,局部变量值等,特点是读写速度最快,一个进程对应一个,操作方式类似于数据结构中的栈。其数据大小是固定的,栈的大小比堆小, 栈区的地址是连续的,地址按照分配的顺序,由大到小顺序排列。(栈可能会有栈溢出的问题,如果出现了栈溢出,那么程序将会崩溃。) ==iphone的栈区大小只有512k(默认) ==
堆(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收(内存泄漏) 堆是程序执行过程中的公共内存区域,每个程序有一个唯一的堆。堆可以由这个程序的多个线程共同访问。堆的大小是可以动态分配的, 堆区的地址是不连续的。一般堆分配内存需要通过malloc、alloc、copy等关键字来修饰 。不同于数据结构中的堆,这里的堆的分配方式类似于链表。
全局区(静态区)(static):程序结束后由系统释放 BSS段 全局变量和静态变量被分配到同一块内存中 ,static 关键字定义的变量在程序执行中 只会被执行一次
常量区(数据段): 程序结束后由系统释放 这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。
代码区(Code) : 程序结束后由系统释放 存放程序 编译链接 后的二进制可执行代码
一个C++的小栗子
//main.cpp
int a = 0; 全局区
char *p1; 全局区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456/0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456/0放在常量区,编译器可能会将它与p3所指向的"123456"
优化成一个地方。
}
OC栗子
int main(int argc, const char * argv[]) {
// 局部变量是保存在栈区的
// 栈区变量出了作用域之后,就会被销毁
NSInteger count = 10;
NSLog(@"%zd", count);
// 局部变量是保存在栈区的
// 赋值语句右侧,使用 new 方法创建的对象是保存在堆区的
// newCar 变量中,记录的是堆区的地址
// 在 OC 中,有内存管理机制,叫做 ARC,可以自动管理 OC 代码创建对象的生命周期
// 因此,在开发 OC 程序的时候,程序员通常不需要考虑内存释放的工作
// C 语言使用 malloc、calloc、realloc 函数分配的空间,需要使用 free 函数释放
MyCar *newCar = [MyCar new];
NSLog(@"%@", newCar);
return 0;
}
常量 : const 关键字保证其后修饰的常量的值不允许被修改 不要将常量定义在头文件.h中
extern const NSInteger cardNo;
extern的作用: extern关键字,表示该常量的数值,是在其他文件中设置的,
外部可以直接使用此常量.
另外:
1.栈 不会产生碎片
2.堆:频繁地malloc和free会产生内存碎片(有点类似磁盘碎片),因为c分配动态内存时是寻找匹配的内存的