Source code

Memory strategy

Although after entering the background, the work of the program is greatly limited, but we always do not want the application to be killed by the operating system suddenly, interrupting the important background work. Background applications are killed, which affects not only the user experience, such as the music being played suddenly stops and the voice being navigated is interrupted unexpectedly. In the background, it is not possible to kill the application due to the abnormal operation of the system. Therefore, how to reduce the application being killed in the background is a problem worthy of consideration

How background applications are killed

Apart from being killed because the application stays in the background for too long, the most important reason is that the application is killed because of memory problems. Memory is very different from other hardware resources

When the demand of resources is more than the resources can supply, the performance of CPU will decline, and the operating system will kill the background applications in order to reclaim memory

We can divide the device memory into four areas, including system, background, foreign and free.

  • The system is fixed occupied after the device is turned on, and it is almost impossible to be accessed by our application

  • Background is used by applications running in the background and will be recycled when there is insufficient memory

  • The foreground belongs to the memory used by the current running application

  • Free belongs to allocable memory, and the system will give priority to allocating this part of memory to the application

In this case, if the device you just started does not include the memory of the device you just started

The application exits the foreground at this time. Because there is enough free memory to allocate, the system will not recover the memory temporarily

Then the user opens a new application, but the new application needs a lot of memory, which exceeds the available memory of the device

Then the system sends a memory warning notice to your application. The system reclaims the temporarily unused memory and then has enough memory for the new application

Or if you don't send warning at all, your app will be killed directly:

Memory warning

Memory warning will be issued when the system is aware that there may not be more free memory used, including notification and proxy. Generally speaking, we can divide warning into active and active strategies according to different roles of developers

Memory classification

Before understanding the differences between the two coping strategies, we need to understand that for each running application, the memory that can be automatically cleared by the system can be divided into two categories: (the memory here is limited to the memory that can be allocated actively and can be released at any time)

Dirty

The content on the left will be stored by us using array or dictionary. Most of the time, for smoother results, we may cache data outside the page, such as preloading cells, precomputing height, and so on. It determines the current state of the data, and so on. The system will not save the memory until it is recycled

Purgeable

The right side stores the data that may have been used. For example, the user requests a large amount of data after entering the recommendation function. The nscache is used to cache the data in memory to quickly display the content when re entering the recommendation page. This part of data is obviously unused data. This part of the memory will be directly cleared by the system after reallocation

In terms of memory classification, reducing the amount of dirty data and increasing the amount of Purgeable can reduce the pressure of memory usage

Passive strategy

The reason why we have to solve these problems is that we have to solve the problems through the passive operation system before we try to solve them

NSPurgeableData

As mentioned above, the memory marked as Purgeable will be directly cleaned up by the system and then reallocated. This cleaning process occurs before the warning is issued. After Purgeable, if there is not enough memory available for cleaning up. Nspluggeabledata is a subclass of nsdata, which provides a similar dispatch_ group_ An integer variable is used to store the usage state. When the value is 0, the data is in the unused state

 Nspurgeabledata * purgeabledata = [[nspurgeabledata alloc] initwithbytes: filedata. Bytes length: filedata. Length]; 
 [purgeabledata begincontentaccess]; 
 / / value + 1, start using data 
... 
 [purgeabledata endcontentaccess]; / / / value - 1, the end of using data 
... 
 / / after a long time, if the data cannot be accessed, it indicates that it is recycled, and you need to re create 
 if (! [purgeabledata) begincontentaccess] {purgeabledata = [[nspurgeabledata alloc] initwithbytes: filedata. Bytes "length: filedata. Length]; 
  }
  [purgeableData beginContentAccess];

NSCache

Nscache provides a simple dictionary like interface for accessing data and setting a maximum cache size. The data in nscache is considered to be of Purgeable type. When the cache reaches the maximum value, the least used data will be eliminated by LRU algorithm, and it will also be recycled by the system before warning

memory warning

After cleaning up the Purgeable data, if the memory is still insufficient, the system will issue a memory warning to all active applications, and then the developer will take the initiative to deal with it

Proactive strategy

In terms of operation, Purgeable data needs to be maintained by developers, which is more like an active mechanism. However, when the memory is not enough, the system will automatically reclaim the memory without requiring the developers to do more work. Therefore, this mechanism is classified as a passive strategy. Active strategy should be the work of developers after receiving memory warning:

 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    /// release data cannot keep the application running
    [self.database close]; 
}

- (void)didReceiveMemoryWarningNotification: (NSNotification *)notification {
    /// release data cannot keep the application running
    [self.dataSource removeAllObjects];
    [self.images removeAllObjects];
    [self cleanAllAnimatorViews];
}

Processing warning is almost the only effective method for developers, but this method is not completely reliable. If it depends on the memory warnings issued by the system, there are several risk points:

  • Memory warning is issued for all running applications, which means that the CPU may not be busy to handle your work at the same time

  • If it just belongs to the back column of the running application queue, after the Purgeable data is recycled and other applications respond to the warning, there is still not enough memory, and it may be directly killed without the opportunity to process it

So even if dealing with warnings is almost the only way, there are still other ways to think. If we map part of the data to disk, the application can run with minimal memory consumption

file map

File mapping is not a panacea. Every time the data is modified, it will be updated to the same location on the disk. Even though SSD has a strong access capability, it is still a big overhead. Your data should always meet these requirements before you consider using file mapping:

  • Necessary data for application operation. For example, music application plays music information, player class

  • The cost of restoration or construction is high. If the cost is not high, there is no loss in rebuilding

  • The data is easy to calculate. If the data is always changing, it will cause serious interference to the calculation of file size

  • The data hardly changes. The less change, the higher the storage value

These conditions determine that file mapping is not applicable to all data, but is basically applicable to configuration files, image data, text data and so on, and these data often occupy a large part of memory

When a large amount of data is integrated into another piece of data. In the case of the same data size, the memory efficiency of the system processing multiple block file mapping is much lower. In addition, too many virtual memory blocks will cause the system to forcibly kill the application. Nsdata allows us to use options to provide file mapping:

 typedef NS_ OPTIONS(NSUInteger, NSDataReadingOptions) {
    NSDataReadingMappedIfSafe =   1UL << 0,
    NSDataReadingUncached = 1UL << 1,
    NSDataReadingMappedAlways API_ AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = 1UL << 3,
};

other

Due to Apple's Sandbox mechanism, we used to pay more attention to the memory usage within the application, and less attention to the memory problems that may occur when the application is running in the background

You should always think that something other than your application will be hostile to you and may destroy you

Therefore, we should learn how to use the memory usage strategy reasonably to resist the attack outside the application. Of course, the most important thing is that we can tell QA in a reasonable way: hum, the memory usage of the application has dropped!

Author: sindri's nest

Link: https://www.jianshu.com/p/b81ab8b583c3

fabulous ( one )

This paper is written by Contributors Article, address: https://blog.isoyu.com/archives/neicuncelue.html
use Knowledge sharing signature 4.0 International license agreement. Except for the reprint / source, they are all original or translated by our website. Please sign before reprinting. Last editing time: June 11, 2018 at 04:56 PM

Hot articles

Comment

[required]

invisibility?

Please do not submit and wait three seconds later