set-expected-allocation-in-generation-2-after-gc &key expected-other-mbs expected-cons-mbs max-needed-other-mbs max-needed-cons-mbs => prev-expected-other-mbs prev-expected-cons-mbs prev-max-needed-other-mbs prev-max-needed-cons-mbs
set-expected-allocation-in-generation-2-after-gc is intended to improve the behavior of the application, but it may also degrade the performance if not used appropriately. It sets internal values associated with each of the parameters max-needed-other-mbs, max-needed-cons-mbs, expected-other-mbs and expected-cons-mbs.
All parameters and return values are in megabytes. If any parameter is
nil or is larger than the maximum, which is 65535, then the maximum is used for that parameter. expected-other-mbs defaults to its current internal value and max-needed-other-mbs defaults to the maximum of its current internal value and expected-other-mbs (see below). Likewise for expected-cons-mbs and max-needed-cons-mbs. LispWorks starts with all internal values set to the maximum.
The main purpose of
set-expected-allocation-in-generation-2-after-gc is to tell the GC what you expect to be the maximum allocated megabytes in generation 2 after a GC of generation 2. That allows LispWorks to perform a better GC in situations where it does not have enough memory to copy all of generation 2. You set this separately for Other and
cons objects, by supplying expected-other-mbs and expected-cons-mbs. Note that Other does not include Large and Static objects.
In situations where LispWorks cannot get enough memory from the operating system to copy all of generation 2, but can get the expected size that you have set, the GC is faster than it would have been if the expected size was not set (that is, set to the maximum), and more importantly, the memory usage after the GC will be smaller (sometimes much smaller). On the other hand, if the expected size is set too low in such a situation, then the GC is a little slower, and more importantly, the memory usage after the GC is larger than it would have been if the expected size was not set, until the next GC of generation 2 where the expectation is met. Thus for the expected size setting to be useful, it needs to be met (that is, the allocated size after GC must be less than the setting) in almost all GCs of generation 2. It probably needs to met more than 90% in the GCs to be useful.
The function get-maximum-allocated-in-generation-2-after-gc is designed to allow you to find out what values to use. You exercise the application by trying to do anything that an end user may do, and then call get-maximum-allocated-in-generation-2-after-gc to see the maximums. Note that with normal settings, the points at which GC of generation 2 is invoked (and hence the amount alive after it) are not well defined. Therefore, you need to exercise the application more than once to find the correct numbers. Alternatively, if you block GC of generation 2 (by using set-generation-2-gc-options) and invoke the GC yourself, you can be more confident that you know the memory state at the time the GC is invoked. Alternatively, instead of calling get-maximum-allocated-in-generation-2-after-gc you can use the second and third return values of (count-gen-num-allocation 2), or the values that room reports for "Other 2" and "Cons 2". You can use set-automatic-gc-callback to set a function that will be called immediately after GC of generation 2.
set-expected-allocation-in-generation-2-after-gc ensures that the settings of max-needed-other-mbs and max-needed-cons-mbs are always equal or larger than the setting of expected-other-mbs and expected-cons-mbs respectively, by enlarging the setting of max-needed-other-mbs or max-needed-cons-mbs when needed.
Smaller values of max-needed-other-mbs and max-needed-cons-mbs cause LispWorks to use less memory in situations where it could get more memory from the operating system than they specify. That means the memory peak that happens during the GC will be smaller. That should not have much effect the performance of LispWorks itself, but when the operating system is close to running out of memory, that may prevent it from actually running out of memory while the GC is running. On the other hand, if the GC requires more than max-needed-other-mbs or max-needed-cons-mbs, it will try to get more memory during the GC operation, and if this fails it has larger effect on performance than failure to allocate during the initialization of the GC.
set-expected-allocation-in-generation-2-after-gc is useful in the situation when you have a "generation leak", that is objects live long enough to be promoted from generation 1 to 2 but die soon afterwards, and you do not have much allocated in generation 2 otherwise. In this case, the size of the live objects after a call to GC of generation 2 would be small, which means that the GC will be fast because the timing of a GC that works as planned is dependent on the amount allocated after the GC.
However, the memory peak will still be dependent on the size of generation 2 before the GC, which may cause failure to get memory from the operating system, and hence result in a slower and much less effective GC. Setting the values reduces the chance of such a failure, and reduces the memory usage even in situation where LispWorks could get the memory. Therefore, as long as the settings are correct (that is, in the vast majority of GCs of generation 2, the amount allocated after the GC is less than the setting) it can improve the performance of LispWorks significantly.
LispWorks User Guide and Reference Manual - 20 Sep 2017