Bug 24015

GemStone/S, 6.7.2, 6.7.1, 6.7, 6.6.5, 6.6.4,,, 6.6.3, 6.6.2, 6.6.1, 6.6, 6.5.8,, 6.5.7, 6.5.6, 6.5.5, 6.5.4, 6.5.2, 6.5.1, 6.5, 6.3.1, 6.3, 6.2.x, 6.2, 6.1.6, 6.1.5, 6.1.x, 6.0.x,, 5.1.5, 5.1.4


AllSymbols collection is not scalable

Customers with AllSymbols dictionaries larger than half a million objects
may, under certain circumstances, experience performance problems. Symptoms
can include:

*  occasional extremely long login times shortly after the Stone has been


*  the GcGem can periodically consume a large proportion of CPU cycles
and space in the shared page cache

(or both).


You can avoid these problems with some combination of the following five

*  Minimize the use of symbols in your application. Symbols are appropriate

  --  You need the canonical behavior.
  --  Use of symbols can significantly avoid redundant Strings.

*  Avoid creating temporary symbols. GemStone does not automatically remove
symbols from AllSymbols when they are no longer referenced by any other
object. If you create a symbol, use it once, and discard it, the symbol
will continue to use space in AllSymbols until you explicitly remove it.

*  Remove unused symbols.
   1. Make sure that the unused symbol is really not used, or you could
create a noncanonical symbol that is equal, but not identical, to one in
AllSymbols, thus causing symbol lookup failures.

   2. Execute:
         AllSymbols remove: #myUnusedSymbol
   (replacing myUnusedSymbol with the actual symbol name).

*  Minimize the number of possible collision buckets used by AllSymbols.
Fewer, larger collision buckets may increase the cost of individual symbol
lookups, but significantly decrease the cost of the GcGem background operation
and improve total system performance. A good rule of thumb is to allow
up to an average of 1000 symbols per collision bucket. The following code
rebuilds AllSymbols if necessary according to this guideline.

    | numSymbols numCollisionBuckets defaultSize |
    defaultSize := 1010.
    numSymbols := AllSymbols size.
    numCollisionBuckets := ( AllSymbols size // 1000 ) max: defaultSize.
    ((AllSymbols basicSize // 2 - 2) ~= numCollisionBuckets ) ifTrue: [
        AllSymbols rebuildTable: numCollisionBuckets ].

*  Recluster AllSymbols periodically to keep AllSymbols and its collision
buckets on as few a number of data pages as possible.

        System clusterAllSymbols


Last updated: