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 ...
随机推荐
- 洛谷P1480 A/B Problem(高精除高精)
P1480 A/B Problem 题目描述 输入两个整数a,b,输出它们的商(a<=10^5000,b<=10^9) 输入输出格式 输入格式: 两行,第一行是被除数,第二行是除数. 输出 ...
- Unity---UNet学习(2)----简单mmo游戏实现
1.实现步骤 新建空物体Controller,添加Network Manager.HUD组件. 创建Player模型,添加Inentity组件. Player添加脚本控制移动,只有当为本地用户才执行. ...
- MySQL zip安装问题
今天安装mysql的压缩版出现了问题,就是服务总是启动不了,折腾了两三个小时.后面实在是想不明白,就直接把注册表的东西删了. 如果你之前安装过mysql,则进行删除mysql:E:\work\mysq ...
- C#线程入门(一)
入门 概述与概念 创建和开始使用多线程 线程同步基础 同步要领 锁和线程安全 Interrupt 和 Abort 线程状态 等待句柄 同步环境 使用多线程 单元模式和Windows Forms Bac ...
- 方程的解_NOI导刊2010提高(01) 组合数
题目描述 佳佳碰到了一个难题,请你来帮忙解决. 对于不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整数,g(x)=x^x mod 1000(即x^x除以1000的余数), ...
- JMeter - 如何创建可重用和模块化测试脚本
概述: 我的应用程序几乎没有业务关键流程,我们可以从中提出不同的业务工作流程.当我试图在JMeter中提出性能测试脚本时,我需要找到一些方法来创建可重用/模块化的测试脚本.这样我就可以创建不同的工作流 ...
- Sublime编写React必备插件
我终于看到了我要的攻略,sublime自带的format实在是不能看不能看不能看. 攻略地址:http://www.jianshu.com/p/ecf6c802fdc5?open_source=wei ...
- Codeforces Round #129 (Div. 2) A
Description The Little Elephant loves Ukraine very much. Most of all he loves town Rozdol (ukr. &quo ...
- 03.Spring IoC 容器 - 初始化
基本概念 Spring IoC 容器的初始化过程在监听器 ContextLoaderListener 类中定义. 具体由该类的的 configureAndRefreshWebApplicationCo ...
- OpenStack git cmd
文件流转的三个工作区域:Git 的工作目录,暂存区域,以及本地仓库. 基本的 Git 工作流程如下: 在工作目录中修改某些文件. 对修改后的文件进行快照,然后保存到暂存区域. 提交更新,将保存在暂存区 ...