美文网首页
难道栈空间有缓存?

难道栈空间有缓存?

作者: 康小曹 | 来源:发表于2020-10-30 11:44 被阅读0次

最近发现一个有意思的现象,先贴代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self test2];
    [self test2];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self test2];
}

- (void)test2 {
    NSObject *obj = [NSObject new];
    NSLog(@"caoxk_debug:obj address:%p",&obj);
    NSLog(@"caoxk_debug:obj address:%p",obj);
}

test2 是函数,obj 是栈指针指向了堆空间中的对象实例,按理来说,每次调用 test2,栈空间中的 obj 变量都应该会重新创建,且指向不同的 obj 对象;
执行结果确令人大跌眼镜:

2020-10-29 16:26:48.293 XKHTMLParser[2315:26254180] caoxk_debug:obj address:0x7ffeed57b608
2020-10-29 16:26:48.294 XKHTMLParser[2315:26254180] caoxk_debug:obj address:0x600000007710
2020-10-29 16:26:48.298 XKHTMLParser[2315:26254180] XKObject-dealloc
2020-10-29 16:26:48.298 XKHTMLParser[2315:26254180] caoxk_debug:obj address:0x7ffeed57b608
2020-10-29 16:26:48.299 XKHTMLParser[2315:26254180] caoxk_debug:obj address:0x6080000077c0
2020-10-29 16:26:48.299 XKHTMLParser[2315:26254180] XKObject-dealloc
2020-10-29 16:26:48.301 XKHTMLParser[2315:26254180] caoxk_debug:obj address:0x7ffeed57b948
2020-10-29 16:26:48.301 XKHTMLParser[2315:26254180] caoxk_debug:obj address:0x6080000077c0
2020-10-29 16:26:48.303 XKHTMLParser[2315:26254180] XKObject-dealloc

有时候是:

2020-10-29 16:44:21.230 XKHTMLParser[2867:26309417] caoxk_debug:obj address:0x7ffee8c72608
2020-10-29 16:44:21.231 XKHTMLParser[2867:26309417] caoxk_debug:obj address:0x608000001b60
2020-10-29 16:44:21.231 XKHTMLParser[2867:26309417] XKObject-dealloc
2020-10-29 16:44:21.231 XKHTMLParser[2867:26309417] caoxk_debug:obj address:0x7ffee8c72608
2020-10-29 16:44:21.231 XKHTMLParser[2867:26309417] caoxk_debug:obj address:0x608000001b60
2020-10-29 16:44:21.232 XKHTMLParser[2867:26309417] XKObject-dealloc
2020-10-29 16:44:21.232 XKHTMLParser[2867:26309417] caoxk_debug:obj address:0x7ffee8c72948
2020-10-29 16:44:21.232 XKHTMLParser[2867:26309417] caoxk_debug:obj address:0x608000001b60
2020-10-29 16:44:21.233 XKHTMLParser[2867:26309417] XKObject-dealloc

也就是说,栈中自动变量不会立马销毁,也不一定每次都产生新的栈变量。栈变量所指向的的对象即使 dealloc ,也不一定不是同一个。

可能的原因有两个:

  1. 缓存的优化,一定时间内再次被使用,会使用缓存;
  2. 空间地址一样,但实际上时新创建的对象或者是变量;

具体原因还真不好说,因为即使是:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self test2];
    NSObject *obj1 = [NSObject new];
    NSObject *obj2 = [NSObject new];
    NSObject *obj3 = [NSObject new];
    NSObject *obj4 = [NSObject new];

    [self test2];
}

最后的结果也是:

2020-10-29 16:48:36.847 XKHTMLParser[3038:26321400] caoxk_debug:obj address:0x7ffee1e415e8
2020-10-29 16:48:36.848 XKHTMLParser[3038:26321400] caoxk_debug:obj address:0x6000000153c0
2020-10-29 16:48:36.848 XKHTMLParser[3038:26321400] XKObject-dealloc
2020-10-29 16:48:36.848 XKHTMLParser[3038:26321400] caoxk_debug:obj address:0x7ffee1e415e8
2020-10-29 16:48:36.849 XKHTMLParser[3038:26321400] caoxk_debug:obj address:0x600000015440
2020-10-29 16:48:36.849 XKHTMLParser[3038:26321400] XKObject-dealloc
2020-10-29 16:48:36.849 XKHTMLParser[3038:26321400] caoxk_debug:obj address:0x7ffee1e41948
2020-10-29 16:48:36.849 XKHTMLParser[3038:26321400] caoxk_debug:obj address:0x608000015490
2020-10-29 16:48:36.850 XKHTMLParser[3038:26321400] XKObject-dealloc

如上,虽然对象实例的地址发生了变化,但是栈中的自动变量地址仍然一样。

猜测:
不同于安卓/java/js,垃圾回收机制定时去回收,iOS 中不太可能去做对象或者变量的缓存机制,因为这个量实在太大了。所以,短期内栈或者堆的空间重新被使用,这种解释比较合理。

后续:
汇编方面的知识还是要再复习一遍,堆栈的处理这块应该可以去解释这个现象。另外这个现象也很可能和cpu架构有关,不同的架构可能有不同的处理,不要太过于纠结。

相关文章

  • 难道栈空间有缓存?

    最近发现一个有意思的现象,先贴代码: test2 是函数,obj 是栈指针指向了堆空间中的对象实例,按理来说,每次...

  • 内存缓存-go

    GO 内存缓存 CPU 有缓存:L1,L2,L3 不同等级缓存执行速度不一样,空间也不一样。 内存缓存:有栈有堆,...

  • 1.1堆和栈

    1.栈(stack)和堆(heap) stack:自动分配和释放的内存空间。 栈使用的是[一级缓存], 他们通常都...

  • JVM 运行时数据区内部结构

    线程私有:程序计数器、本地方法栈、虚拟方法栈 线程共有:堆、堆外内存(永久代或者元空间、代码缓存); Rumtim...

  • [libco] 协程栈空间

    协程“栈”空间,有独立栈和共享栈,重点理解一下协程共享栈。 文章来源:[libco] 协程栈空间[https://...

  • JVM(二)分区

    一、分区介绍 每个线程:独立包括程序计数器、栈、本地栈 线程间共享:堆、堆外内存(方法区、永久代或元空间、代码缓存...

  • iOS逆向-从汇编代码理解函数调用栈

    程序的栈空间有什么特点呢?首先会想到的就是,栈空间是往低地址增长的,当调用一个函数时,先开辟栈空间,用来存放当前函...

  • 栈的扩展

    共享栈 两个栈 共享一片存储空间 栈s1 需要存6个 而栈s2 只需要存1个 栈s2 有多余的存储空间 但是它不需...

  • c#中的堆与栈

    简介:我们把内存分为堆空间和栈空间线程堆栈:简称栈 Stack 栈空间比较小,但是读取速度快托管堆:...

  • 5.堆和栈

    1. 简介: 我们把内存分为堆空间和栈空间 栈空间比较小,但是读取速度快堆空间比较大,但是读取速度慢 2. 栈: ...

网友评论

      本文标题:难道栈空间有缓存?

      本文链接:https://www.haomeiwen.com/subject/antdvktx.html