猫猫整理问题之:内存堆栈

猫猫分享

原文地址:http://blog.csdn.net/u013357243?viewmode=contents

内存

数据在内存中的存放

在计算机中,运行的应用程序的数据都是保存在内存中的。

不同类型的数据,保存的内存区域不同,其中包括:

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的区别吧。

ps:新建iOS交流学习群:304570962

可以加猫猫QQ:1764541256 或则微信znycat

让我们一起努力学习吧。

原文:http://blog.csdn.net/u013357243?viewmode=contents

时间: 2024-10-17 10:21:49

猫猫整理问题之:内存堆栈的相关文章

STM32/GD32上内存堆栈溢出探测研究

无数次遭受堆栈溢出折磨,随着系统变得复杂,故障点越来越难以查找!主要溢出情况如下:1,一般RAM最后两块空间是堆Heap和栈Stack,堆从下往上用,栈从上往下用,任意一个用完,都会进入对方的空间2,如果栈用完,进入堆的空间,这个时候系统是不会有任何异常的,也就是说,栈底没有什么意义.除非堆和栈指针重叠,否则大家相安无事,尽管栈用了堆的3,如果栈用完进入堆,并且还碰到了堆的空间,这个时候系统仍然没有异常,但是堆栈会相互修改数据.最悲剧的就是栈里面保存的然会地址lr,一旦被堆指针修改,返回的时候就

PHP对象在内存堆栈中的分配

PHP对象在内存堆栈中的分配 对象在PHP里面和整型.浮点型一样,也是一种数据类,都是存储不同类型数据用的, 在运行的时候都要加载到内存中去用,那么对象在内存里面是怎么体现的呢?内存从逻辑上说大体上是分为4段,栈空间段.堆空间段.代码段.初始化静态段,程序里面不同的声明放在不同的内存段里面. 数据段(data segment)通常是指用来存放程序中已初始化且不为0的全局变量如:静态变量和常量 代码段(code segment / text segment)通常是指用来存放程序执行代码的一块内存区

猫猫整理问题之:copy,对象自定义copy

猫猫分享,必须精品 原文地址:http://blog.csdn.net/u013357243?viewmode=contents copy copy的正目的 copy 目的:建立一个副本,彼此修改,各不干扰 Copy(不可变)和MutableCopy(可变)针对Foundation框架的数据类型. 对于自定义类,copy就是可变的. 可变数组的copy 这里用NSMutableArray为例子. // 可变=>可变&不可变,内存地址都会变化 void copyDemo1() { NSMuta

内存堆栈的区别

在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到.但对于很多的初学着来说,堆栈是一个很模糊的概念. 堆栈:一种数据结构.一个在程序运行时用于存放的地方,这可能是很多初学者的认识. 数据结构的栈和堆 首先在数据结构上要知道堆栈,尽管我们这么称呼它,但实际上堆栈是两种数据结构:堆和栈. 堆和栈都是一种数据项按序排列的数据结构. 栈就像装数据的桶或箱子 我们先从大家比较熟悉的栈说起吧,它是一种具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取. 这就如同我们要取出

Java细节整理——数组与内存控制

重点:使用Java数组之前,必须对数组对象进行初始化. 当数组的所有元素都被分配了合适的内存空间,并指定了初始值时,数组的初始化完成.程序以后将不能重新改变数组对象在内存中的位置和大小. 知识点整理: 1.数组的初始化有以下两种方式: 1)静态初始化:初始化时由程序员显示指定每个数组元素的初始值,由系统决定数组的长度. 2)动态初始化:初始化时程序员只指定数组的长度,由系统为数组元素分配初始值. 不管使用哪种方式初始化Java数组,一旦初始化完成,该数组的长度就不可改变. 代码示例: publi

JS 内存堆栈原理(注销引用对象后带来的问题)

var a = { name: 123}; var b = a; a.name; 123 b.name; 123 a.name = 'wolf'; "wolf" b.name "wolf" a.name = null; //注销此引用对象的内存,引用此引用对象的对象,失去对引用对象的引用,获得属于自己的引用对象副本; null b.name null a = null; null b Object {name: null}

C语言:一个涉及指针函数返回值与printf乱码、内存堆栈的经典案例

一个奇怪的C语言问题,涉及到指针.数组.堆栈.以及printf.下面实现: 整数向字符串的转换,返回字符串指针,并在main函数中调用printf显示. #include<stdio.h> #include<stdlib.h> #include<string.h> char* swich(int n) { char A[20],B[20]; char*p;//=(char*)malloc(4*sizeof(char)); int i=0,a; int minus=0;

eclipse JVM Tomcat 内存堆栈大小设置

1,  设置Eclipse内存使用情况 修改eclipse根目录下的eclipse.ini文件 -vmargs  //虚拟机设置 -Xms40m //初始内存 -Xmx256m //最大内存 -Xmn16m //最小内存 -XX:PermSize=128M //非堆内存 -XX:MaxPermSize=256M 2,  JVM内存设置 打开eclipse  window-preferences-Java -Installed JREs -Edit -Default VM Arguments 在V

openjdk-alpine镜像无法打印线程堆栈和内存堆栈问题

基于openjdk:8u171-alpine构建的java镜像,使用jstack命令打印线程的时候会提示以下错误: /opt # ps -ef PID USER TIME COMMAND 1 root 0:28 /usr/lib/jvm/java-1.8-openjdk/bin/java -jar /test/lib/test.jar 66 root 0:00 /bin/sh 70 root 0:00 ps /opt # jstack 1 1: Unable to get pid of Linu