Mac/iOS 野指针&内存不足问题&内存碎片问题分析
观看此篇文章前需掌握理论知识:https://bbs.huaweicloud.com/blogs/417232
野指针问题
故名思意,野指针问题就是指针指向了一个已经释放的内存块,系统是如何检测到野指针问题的呢,下面举例说明
1、初始状态,p1、p2指向了slotK+1,当前block的meta已经有指向的内容(有释放)
2、free(p1),slotK+1的内容变成了结构体nanov2_free_slot_t,guard内容为当前slot的指针 ^ nanozone.cookie,next_slot指向了slotN
3、访问p2,此时如果是读取数据,slok+1的数据已经不是原有数据,读取没有任何意义,但是不会崩溃
写入p2,会破坏nanov2_free_slot_t结构体,此时并不会异常。
4、用户malloc新的内存,如果刚好返回的是slotK+1,系统会首先校验slotK+1的guard,如果异常会报
怎么校验呢:
guard ^ cookie = ptr;,不满足则异常
思考:如何让p2在写入时就报异常呢?
措施:
1、申请内存时: 在申请的内存前面写上size,并返回size占内存的偏移
这样如果在申请后发生越界,则可以直接通过前缀判断出越界问题。
2、内存释放后,数据段前面写入特殊flag
这时候如果访问p时,p的前缀为flag,则代表发生野指针问题。
其实苹果有相应功能的开关。只需要打开即可
Malloc Scribble:malloc时将内存全部变为0xaaaaa...,释放后变成0x5555,效果不明显,用处不大
Guard Malloc:malloc的内存前缀加上0xdeadbeefdeadbeef,释放后前缀删掉,只要没有此前缀的内存访问都会异常
Address Sanitizer:原理更复杂,释放后的地址会被标记为poisoned,释放后访问会被检测到并崩溃
应用场景更广:
- Use after free
- Heap buffer overflow
- Stack buffer overflow
- Global buffer overflow
- Use after return,
- Use after scope
- Initialization order bugs
- Memory leaks
内存不足问题
有时候会报内存不足问题,但是实际上可以看到还有100mb左右的内存,为什么会报内存不足呢?
通过nano内存管理篇的学习,我们清楚了内存是分级的,特别对iOS来说,只有1个region,那么16B内存只有2MB,超过了2MB就会报内存不足。
因此,在使用内存时要合理的分配
内存碎片
结合nano内存的分析可知,如果故意构建每个block都只保留1个slot,则会导致大范围的内存碎片,所以尽量的增大Blocks中绿色slot的部分,可以降低内存碎片
Xcode导出memgraph文件,文件中包含了内存碎片相关内容
vmmap -summary *.memgraph
- 点赞
- 收藏
- 关注作者
评论(0)