A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://www.lispworks.com/documentation/lw71/LW/html/lw-82.htm below:

11.5 The Mobile GC

11.5.3.1 Response to low memory

Mobile platforms typically inform applications when memory availability becomes low. On Android this is done by the onTrimMemory or onLowMemory methods and on iOS by the didReceiveMemoryWarning method. It is probably a good idea to respond to these methods, but it is not essential.

In your implementation of these methods, you should release any system resources that can be released without loss and also try to reduce the memory used by Lisp data. Since the GC sometimes temporarily requires more memory during an operation, it may be a bad idea to do a GC once you get the warning. The function reduce-memory is provided to reduce memory usage without requiring more memory temporarily. Note that gc-generation can do a much better job than reduce-memory in general, but it may require more memory temporarily.

Calling reduce-memory with argument nil (the default) just releases any reserved memory that LispWorks has kept. It is fast and probably always a good idea. However, with argument nil, reduce-memory does not perform any GC operation, which in principle could release more memory. Because a GC takes time, it is not obvious whether it worth the trouble.

Calling reduce-memory with 0 or 1 causes a GC of generation 0 or 1, which is probably fast enough (unless promotion of generation 1 is blocked and generation 1 grows), but will not typically release much memory.

Calling reduce-memory with 2 (or, equivalently, T), or even :aggressive, can release much more memory, but takes more time, depending on the size of generation 2. Unless it is likely to release a large amount, it is probably not worth it. Thus, unless you know that generation 2 contains a lot of dead objects, you should only call reduce-memory with nil, or maybe 0 or 1.

If you call reduce-memory with a non-nil argument, you should first clear any caches that you have kept, so their contents can be GCed.

To be able to reduce memory usage, reduce-memory needs reserved memory to perform a copying GC. Since reduce-memory never obtains more memory from the operating system, its effectiveness depends on the amount of reserved memory that it has when it is called. Moreover, any call to reduce-memory frees all of the reserved memory (once the GC has occurred if the argument is non-nil), so calling reduce-memory with non-nil shortly after a previous call with NIL is not going to be effective.

To see how much effect reduce-memory had on the memory, you can look at the output of room (last line with any argument you give it), or the result of room-values. To see how much time it takes, use the time macro or get-internal-real-time.

11.5.3.2 Preventing/reducing GC of generation 2

GC of generations 0 and 1 should normally be fast enough that you do not need to worry about them. GC of generation 2, however, typically takes enough time to be noticeable, and if generation 2 is large (> 100 MB) can take more than a second. Thus you normally want to avoid GC of generation 2.

In a "nicely behaved" application, which we believe is true for most applications, generation 2 never needs to be collected. This is based on the assumption that a nicely behaved application starts with some initialization that allocates long-lived objects, but then enters a "work" phase, where it allocates only short lived objects, which die before they reach generation 2.

Even if there is some "generation leak", that is objects being promoted from generation 1 to 2 that die not long afterwards, the leak may be slow enough that it is not a problem. For example, if your application "leaks" on average 1 kB each second, it would take close to 3 hours of operation to leak 10 MB, which is still too small to worry about (the default minimum size of generation 2 before a GC is 64 MB). So you can usually ignore this kind of leakage and hope that any occasional delay of a second or two after running the application for many hours is not too annoying for the user (though if it only a "generation leak" , you can do better by blocking promotion). If you have a leakage of 100 kB per second, the delay would happen every few minutes, which may be too annoying.

To find if your applications leaks to generation 2, you should periodically log the size of either the whole application or of generation 2. The output of room is the most useful thing to log, but you can also use room-values or count-gen-num-allocation. If the application does leak to generation 2, you should determine if it is a real memory leak, which means that the application accumulates live objects, or just a generation leak, which means that objects live long enough to reach generation 2 and then die. To determine that, call (gc-generation T) (or, equivalently, (clean-down)), continue using the application for a while and then call it again. If the leak is just a "generation leak", then the size of generation 2 after (gc-generation t) should stay (more or less) the same. If it grows, then you have a real memory leak.

If your application is "nicely behaved", generation 2, and hence the whole application, will initially grow, typically by few 10's of megabytes, and then will stay more or less fixed. The size of the whole application will always fluctuate, because generation 0 and 1 fluctuate, but generation 2 should be stable or grow slowly. If this is the case, you probably do not need to do anything further to control memory usage.

If generation 2 does grow, LispWorks will occasionally do a GC of generation 2, which takes a noticeable time (maybe a few seconds if generation 2 is few 100's of megabytes). If the leak is a real memory leak, it will also cause the application to grow indefinitely.

If the leak is a real memory leak, then the GC cannot do anything about it. One possibility is to make the application run for a limited time, for example by monitoring the size and quitting when it reaches some threshold. If quitting and restarting is possible without much loss, that may be a good solution. Most of applications probably want to avoid that though, in which case you will need to figure out what keeps objects alive and fix it. The functions sweep-all-objects, sweep-gen-num-objects and mobile-gc-sweep-objects can be used to check what kind of objects have accumulated. However, whatever keeps the objects is something in your application, and you will have to find it.

If the leak is only a "generation leak", then there are several ways to deal with it:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4