AJ整理问题之:内存堆栈

谁说胖子不能爱 提交于 2020-02-04 05:47:49

 

内存

数据在内存中的存放

在计算机中,运行的应用程序的数据都是保存在内存中的。
不同类型的数据,保存的内存区域不同,其中包括:

1:栈区(stack)由编译器自动分配并释放,一半存放函数的参数值,局部变量等。

2:堆区(heap)由程序员分配和释放,如果程序员不释放,程序结束时,可能会由操作系统回收。

3:全局区(静态区)全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后由系统释放。

上面三个很重要,下面三个了解
4:文字常量区:存放常亮字符串,程序结束后由系统释放。
5:程序代码区:存放函数的二进制代码。
6:寄存器去:用来保存栈顶指针和指令指针(我们基本用不到。。。)。

栈内存区中得数据

栈区内存是压栈的讲究

特点:先进后出。
     系统给自动回收。
     由系统自动分配,速度较快。但程序员是无法控制的。
int sum(int x, int y)
{
    NSLog(@"x: %p, Y: %p", &x, &y);

    int result = x + y;

    NSLog(@"%p", &result);

    return result;
}

void demo1()
{
    // 在栈区中的变量,i本质上对应"内存地址"的"标签"
    // 指针 * 表示指向内容空间的内容 & 表示地址
    int i = 10;
    i = i + 5;

    NSLog(@"==== %d", *(&i));

    int j = 20;

    NSLog(@"i:%p, J:%p", &i, &j);

    int result = sum(i, j);

    NSLog(@"%d %p", result, &result);
}

内存示意图
这里写图片描述


堆内存区中得数据

1:由于栈内存中的空间有限,(iOS=1M,MAC=8M)iOS的应用程序中,对象都是建立在堆中的。
2:堆区包括系统内存和虚拟内存(磁盘开辟缓存),由所有正在运行的应用程序共享使用。
3:堆区中的内存分配由操作系统负责,操作系统
使用一个“链表”统一维护所有已经分配的内存记录。
4:由于堆区是由所有应用程序共享的,操作系统
以匿名【只记录内存地址和大小,不记录具体类型】的方式记录已经分配的内存区域。
5:要访问堆区中得数据,必须通过指针的方式才可以进行,指针的类型决定了访问对中数据的方式。
6:当某一内存区域不再使用时,程序需要通知操作系统回收该内存区域,从而可以保证该内存区域被其他程序再次使用,否则,该区域将永远无法被再次分配,这就是传说中的“内存泄露”。
7:如果某一区域已经被释放,仍然试图访问该区域,会提示“坏内存访问”,这就是传说中的“野指针访问”。
8:相比较栈区,堆区中得效率要低很多,同时容易出现内存碎片。
9:相比较栈区,堆区中得访问方式更加灵活,对象占用的内存也可以更大。

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        // 在堆中所有的变量类型都是匿名访问的
        // 能否访问对象的属性,或者调用方法,"取决于指定变量的类型"
        // 所有堆中的变量都是通过指针来访问的
        id p = [[Person alloc] init];
        [p setName:@"zhangsan"];

        NSLog(@"%@ %p", [p name], p);

        // 1. 将p指向 NULL(地址) => 0
        // 2. 释放p
        // ** 在OC/C++中,nil可以调用任何的方法,都不会报错
        // nil是指针指向NULL的空对象 0
        p = nil;

        NSString *str = p;
        NSLog(@"%ld %p", str.length, p);
    }
    return 0;
}

这里写图片描述

堆区中的内存分配由操作系统负责,操作系统
使用一个“链表”统一维护所有已经分配的内存记录。
链表:这里写图片描述

由上部分代码引申出新的问题:
nil NULL Nil都什么关系?

nil和 null和NSNull的区别

nil是一个对象,而NULL是一个值,我的理解为nil是将对象设置为空,而null是将基本类型设置为空的,个人感觉有点像属性当中,基本类型分配为assign NSString类型一般分配copy,而对象一般用retain。而且我们对于nil调用方法,不会产生crash或者抛出异常。
看一段

nil -> Null-pointer to objective- c object

NIL -> Null-pointer to objective- c class

null-> null pointer to primitive type or absence of data.

看一下用法

NSURL *url = nil;

Class  class = Nil;

int *pointerInt = NULL;

nil是一个对象指针为空,Nil是一个类指针为空,NULL是基本数据类型为空。这些可以理解为nil,Nil, NULL的区别吧。

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!