a low memory warning should only destroy the layer’s bitmap
https://stablekernel.com/view-controller-in-ios-6/
Some of you may have noticed that your view controller in iOS 6 no longer gets sent to viewWillUnload or viewDidUnload. That’s because they don’t automatically unload their views anymore.
Your first thought may be, “Ok, well how do I manually unload my views on a low memory warning? This seems like a step backwards.”
Then you go searching for an answer, and you come up with this:
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
if([self isViewLoaded] && ![[self view] window]) {
[self setView:nil];
}
}
However, this is both unnecessary and potentially harmful because of some changes to the underlying support for UIViews. Therefore, in practice, you rarely need to unload a view controller’s view during a low memory warning. (And in theory, you will never have to.)
But why? If you’ve read my entire iOS programming book, you’ve gained the knowledge that a UIView is a subclass of UIResponder (so that it can receive events) and has a pointer to its own CALayer instance (so that it can be drawn on the screen).
A CALayer is a container for a bitmap image. When a UIView runs its drawRect: method, it is creating the bitmap image for its layer. The rest of a layer’s instance variables (many of which it borrows from its UIView, like its frame and backgroundColor) indicate how and where that bitmap image is composited onto the screen.
But the biggest part of the layer (in terms of memory usage) is that bitmap. A layer itself is only 48 bytes and a standard UIView is only 96 bytes, regardless of their size on the screen. The memory consumption for a layer’s bitmap, however, grows very large depending on the bounds of the layer. For example, a full screen retina-display iPad view can be up to a whopping 12 megabytes.
The approach taken by iOS 6 is that a low memory warning should only destroy the layer’s bitmap, but keep the CALayer and UIView objects intact. This makes sense given the memory consumption of the view and layer are relatively small compared to the bitmap. Additionally, a bitmap can be redrawn by having the view run drawRect: again, so it is not like we’ve lost anything.
In fact, something is gained by this approach: your controller no longer needs to re-populate view content after a low memory warning. For example, consider a view controller that maintained a couple of text fields. If that view controller’s view were to go off screen and a low memory warning were to occur, the view controller must save the text currently in those text fields and repopulate them in viewDidLoad or viewWillAppear:. This is no longer an issue because the text fields are never destroyed, thus they retain their text for when the text field’s bitmap is drawn again. This simplifies a very error-prone section of UIViewController code.
There are some additional smarts built into this process of dumping the layer’s bitmap image that are really cool. First, let’s make sure we understand allocation and deallocation. When a memory is allocated (an object, a bitmap, whatever), an appropriately sized chunk of memory from the heap is marked as “in use” and a pointer to the beginning of that chunk of memory is returned. In the case of an object allocation, we think of that pointer as “the object” but really, it’s just the address of a chunk of “in use” memory.
While a chunk of memory is allocated (“in use”), there are guards that prevent code from using that memory unless it is accessed by going through the pointer that was returned during allocation. In a sense, that memory is safe from being screwed with unless you intend to screw with it.
Deallocation simply removes those guards and marks that chunk of memory as “not in use”. This means that the next time you allocate an object, you can use some or all of that “not in use” memory to form a new allocation. Upon deallocation, the values stored in that chunk of memory do not change. While it is possible to access that deallocated memory again and it may be the same, chances are that the memory has changed in some way. Therefore, it’s never safe to access deallocated memory through the pointer you were given upon allocation.
Now, on to why this matters for views and their layers. Each layer has a contents property that points to an object that represents the layer’s bitmap. The type of this object is a private, opaque class named CABackingStore, which contains the actual bitmap as well as some metadata (like whether or not the image has an alpha channel and how many bytes per pixel are used). Thus, it is the CABackingStore that needs to be destroyed when memory is running low.
However, the neat trick here is that a low memory warning does not destroy a CABackingStore. Instead, if a view is offscreen during a low memory warning, its layer’s CABackingStore is set to “volatile”. The volatile flag (which is not the same as the volatile keyword in C), in this context, is like deallocation in the sense that it allows the memory of the CABackingStore to be allocated for a different purpose. The difference between marking this memory as volatile and deallocating it is that the volatile memory can actually be reclaimed; it is not lost forever.
Consider why this is such an interesting optimization. If a view (more accurately, its layer) were to destroy its backing store, the next time the view went on screen it would have to recreate that backing store by running drawRect:. drawRect: is an expensive call, so avoiding it is very important. By allowing the backing store to be reclaimed, the layer can avoid having its UIView execute drawRect: again.
Of course, it is possible that some time between when the backing store was marked as volatile and the view that owned it goes back on the screen, the memory for that backing store was reallocated for a different purpose. In that case, the view would have to run its drawRect: method again to produce its bitmap.
JULY 12, 2013/BY JOE CONWAYTAGS: CALAYER, IOS 6, VIEW CONTROLLER
a low memory warning should only destroy the layer’s bitmap的更多相关文章
- Zabbix value cache working in low memory mode
Zabbix监控自身时告警"Zabbix value cache working in low memory mode",出现这个问题是因为Zabbix Server的参数Valu ...
- Android进程回收机制LMK(Low Memory Killer)
熟悉Android系统的童鞋都知道,系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来.打开的应用越多,后台缓存的进程也越多.在系统内存不足的情况下,系 ...
- Android内存管理机制之一:low memory killer
转载自http://www.miui.com/thread-29268-1-1.html 准备写这个专题之前,心里是有点忐忑的.首先Android内存管理机制相当复杂,想要讲清楚比较困难:其次对于绝大 ...
- 深挖android low memory killer
对于PC来说,内存是至关重要.如果某个程序发生了内存泄漏,那么一般情况下系统就会将其进程Kill掉.Linux中使用一种名称为OOM(Out Of Memory,内存不足)的机制来完成这个任务,该机制 ...
- [ios]received memory warning
参考:http://blog.sina.com.cn/s/blog_68661bd80101nn6p.html IPhone下每个app可用的内存是被限制的,如果一个app使用的内存超过20M,则系统 ...
- Android进程回收机制LMK(Low Memory Killer)【转】
本文转载自:http://www.cnblogs.com/wytiger/p/5744752.html 熟悉Android系统的童鞋都知道,系统出于体验和性能上的考虑,app在退到后台时系统并不会真正 ...
- numexpr low version warning
runing https://colab.research.google.com/notebooks/mlcc/first_steps_with_tensor_flow.ipynb?hl=zh-cn# ...
- 每个zone的low memory是怎么计算出来的
内核都是试图让活动页和不活动页的数量均衡 在分配内存时每次都会唤醒wakeup_swapd,这个函数会在 现在是不是已经没有全局的LRU表了?已经都变成per cgroup级别的LRU表了吗? ina ...
- Android 线程的正确使用姿势
进程优先级(Process Priority) 线程寄宿在进程当中,线程的生命周期直接被进程所影响,而进程的存活又和其优先级直接相关.在处理进程优先级的时候,大部分人靠直觉都能知道前台进程(Foreg ...
随机推荐
- (linux)安装redis---简装
redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了memcached的不足,它支持存储的value类型相对更多,包括strin ...
- .frm和.ibd恢复数据
昨日晚上开发告诉我不小心truncate两个表的数据,要求还原.结果在阿里云上找到了备份内容,结果是物理备份文件.frm..ibd.心中一万个草泥马啊..没办法,开始还原吧. 1.查看测试机Mysql ...
- HDP3.1 中 YRAN 和 MR2 的内存大小配置的计算方式
Container 是 YARN 中基本的处理单元,它是对内存.CPU等计算的封装.总的来说,每个core每块硬盘 分配2个 container,能获得较好的集群利用率. 1. 确定可用内存大小. 对 ...
- uva1610 聚会游戏(细节处理)
uva1610 聚会游戏(细节处理) 输入一个n(n<=1000且为偶数)个字符串的集合D,找一个长度最短的字符串(不一定要在D中出现)S,使得D中恰好一半字符串小于等于S,另一半大于S.如果有 ...
- 洛谷P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper
P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper 题目描述 A little known fact about Bessie and friends is ...
- [Xcode 实际操作]五、使用表格-(5)设置UITableView的单元格背景颜色
目录:[Swift]Xcode实际操作 本文将演示单元格背景颜色的设置 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //首先添加两个协 ...
- [Xcode 实际操作]四、常用控件-(1)UIButton控件的使用
目录:[Swift]Xcode实际操作 本文将演示按钮控件的使用,按钮是用户界面中最常见的交互控件 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import U ...
- Docker存储卷
六.Docker 存储卷(volume) COW:写时复制 Bind mount volume:手动mount绑定的卷 # docker run --name centos-3 -it -v /dat ...
- POJ1321-棋盘问题
题目链接:点击打开链接 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和 ...
- À peu près là 隐私政策
隐私政策 本应用尊重并保护所有使用服务用户的个人隐私权.为了给您提供更准确.更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息.但本应用将以高度的勤勉.审慎义务对待这些信息.除本隐 ...