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];
    }
}

Copy

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: CALAYERIOS 6VIEW CONTROLLER

时间: 2024-11-07 16:50:13

a low memory warning should only destroy the layer’s bitmap的相关文章

[ios]received memory warning

参考:http://blog.sina.com.cn/s/blog_68661bd80101nn6p.html IPhone下每个app可用的内存是被限制的,如果一个app使用的内存超过20M,则系统会向该app发送Memory Warning消息.苹果公司系统工程师建议,应用程序所占内存不应该超过20MB,开发人员圈内流传着一个粗略的经验法则:当应用程序占用了大约20MB内存时,iphone开始发出内存警告.当应用程序所占内存大约为30MB时,iphone OS会关闭应用程序.收到此消息后,a

【突发问题】Received memory warning.问题

2015-11-02 20:36:31.946 around_iOS[8327:60b] Received memory warning. 2015-11-02 20:36:33.321 around_iOS[8327:60b] Received memory warning. 2015-11-02 20:36:33.503 around_iOS[8327:60b] Received memory warning. 2015-11-02 20:36:33.736 around_iOS[8327:

low memory killer配置的思考

OOM_ADJ对于低内存的时候,我们总是想尽量杀掉background的app,尽量保留persist service(比如输入法),让前台app能够流畅的运行.1,background app的adj尽量设高一些,但是max和mini之前,尽量还是要保留一些差距,这样让系统可以逐步去kill进程,而不是一次杀掉很多.一次杀掉很多app很容易造成系统卡顿.2,previeous app和home launcer的adj一定要独立出来,并且不能设置太低,previous app可能会占用很多的内存

Android 如何将一个app 设置为持久app, 不被low memory kill 关闭

前言 欢迎大家我分享和推荐好用的代码段~~ 声明 欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net 雨季o莫忧离:http://blog.csdn.net/luckkof 正文 [Description] 如何将一个app 设置为常住app, 不被low memory kill 关闭 [Keyword] app 持久 persistent [Solution] 1. 将app 的manifest.xml 中的 application 中添加属性 android:

Android进程回收机制LMK(Low Memory Killer)【转】

本文转载自:http://www.cnblogs.com/wytiger/p/5744752.html 熟悉Android系统的童鞋都知道,系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来.打开的应用越多,后台缓存的进程也越多.在系统内存不足的情况下,系统开始依据自身的一套进程回收机制来判断要kill掉哪些进程,以腾出内存来供给需要的app, 这套杀进程回收内存的机制就叫 Low Memory Killer ,它是基于Linux内核的 OOM K

正确处理 Memory Warning

IPhone下每个app可用的内存是被限制的,如果一个app使用的内存超过20M,则系统会向该app发送Memory Warning消息.收到此消息后,app必须正确处理,否则可能出错或者出现内存泄露. app收到Memory Warning后会调用: UIApplication::didReceiveMemoryWarning -> UIApplicationDelegate::applicationDidReceiveMemoryWarning,然后调用当前所有的viewController

Android中的Low Memory Killer

转载请标明出处: http://blog.csdn.net/yujun411522/article/details/46334123 本文出自:[yujun411522的博客] 在现有的技术条件下,内存永远都是一个吃紧的资源,不用说是PC上会出现内存不足的可能,更不必说在移动设备上了.一旦出现内存不足就会导致系统卡顿,影响用户体验.而Android运行在Linux的基础之上,Linux的内存的使用原则就是不要浪费内存,所以在程序退出时在一段时间内还停留在内存中,这也是我们下一次打开程序时发现快一

numexpr low version warning

runing https://colab.research.google.com/notebooks/mlcc/first_steps_with_tensor_flow.ipynb?hl=zh-cn#scrollTo=gzb10yoVrydW on the ipythong notebook /usr/local/lib/python2.7/dist-packages/pandas/core/computation/check.py:17: UserWarning: The installed

每个zone的low memory是怎么计算出来的

deferred_init_memmap -->deferred_free_range 6801 /*6802  * Initialise min_free_kbytes.6803  *6804  * For small machines we want it small (128k min).  For large machines6805  * we want it large (64MB max).  But it is not linear, because network6806  *