Last Updated October 1, 1999
Applies to 32-bit GemStone/S only
Not Connected Set Basics
- An object in the not connected set is an object which resides on a page but is “not connected” to (referenced by) a persistent object. This is an unusual condition because most not connected objects exist in Local Object Memory (LOM) rather than on a page.
- Each gem keeps track of its own not connected objects in a special hidden set called the not connected set.
- Not connected objects may be committed or uncommitted. A not connected object is said to be committed if it was present in the not connected set during any successful commit. Otherwise the object is considered uncommitted. To determine if a not connected object (or any object) is committed, send the message isCommitted to the object.
- Objects in the not connected set are protected from epoch and markForCollection garbage collection so long as they remain in the not connected set.
- To determine if any object is in the not connected set, execute the following code in GemStone:
System _testIf: self isIn: 3
- The not-connected GC sweeps the objects in the NC set and determines which NC objects are no longer required by the gem (if any). These objects are called not-connected dead objects.
- The not-connected set garbage collection algorithm handles committed NC dead objects differently than uncommitted NC dead objects as follows:
- Uncommitted NC dead objects which are no longer referenced are immediately deleted by the gem.
- Committed NC dead objects which are no longer referenced cannot be deleted because they are part of the committed repository. The gem will remove them from the NC set so they may be collected by the Epoch GC or the markForCollection operations.
- Many not connected objects also turn out to be garbage objects. For this reason, tuning the not connected garbage collection mechanisms can yield substantial gains in performance and reductions in repository growth patterns.
- The not-connected GC can be run manually by executing the following code:
- Because uncommitted NC objects can be reclaimed immediately and committed NC objects cannot, it is sometimes desirable to manually run the NCGC before committing when the NC set is large.
When Bad Things Happen To Good Objects: How Objects Get Into The Not Connected Set
“My Cup Runneth Over”: Overflow From LOM
- All new objects are created in LOM (except for large objects, which will be discussed later).
- LOM is divided into different “spaces”. Older objects are moved between the spaces as new objects are created. The only space whose size can be modified is Old Space. Old Space is another name for a gem’s Temporary Object Cache, the size of which is controlled by the GEM_TEMPOBJ_CACHE_KB setting.
- Garbage objects are automatically removed from LOM by the LOM garbage collector. The algorithm which collects garbage in old space is called MakeRoomInOldSpaace.
- Objects are also typically removed from LOM during a commit. When a gem commits, all objects in LOM which will become persistent are moved out of LOM onto pages.
- If the gem needs to move some objects into Old Space and Old Space is full or does not have enough room to hold the new objects, the MakeRoomInOldSpace routine is executed. If Old Space is still full (or still has insufficient capacity to hold the new objects), the oldest objects in Old Space are moved onto pages in the private page cache. Objects that overflow Old Space in this manner become members of the gem’s not-connected set.
- Objects that overflow Old Space into the not-connected set can never be moved back to Old Space.
- Look for a relationship between the MakeRoomInOldSpaceCount and the NotConnectedObjsSetSize. Establishing that the size of the not connected set increases shortly after the MakeRooimInOldSpace routine runs is a strong indicator that Old Space is overflowing into the not connected set.
- Examine the application code to determine why so many new objects are being created. Are extraneous objects being created? If so, can these be reduced in number, reused, or eliminated?
- Increasing the size of Old Space can reduce or eliminate overflows into the not connected set.
- Examine the commit frequency of the gem. Recall that typically during a commit, many objects are moved out of LOM into page space, thus freeing space in LOM for new objects. Therefore committing more frequently can prevent Old Space from becoming full.
- Examine the size of the Export Set. The export set may be protecting many objects in LOM which otherwise would have been garbage collected.
Too Large To Handle: Creating Large Objects
- A large object is an object that is too large to fit on a single 8KB page.
- Most large objects are some type of collection:
- Byte collections (Strings, Symbols, etc) larger than 8096 characters are large objects.
- OOP collections (Arrays, OrderedCollections, etc) larger than 2024 objects are large objects.
- Unlike small objects, large objects are created in page space rather than in LOM.
- For this reason, large objects are immediately placed in the not connected set when they are created.
- Objects appear in the not connected and the gem has not experienced any MakeRoomInOldSpace or any failed commits. These conditions suggest the not connected objects may be large.
- Determining if an object is large is more complicated than simply asking its physical size. GemStone smalltalk code to perform this function is shown in the Appendix.
- Examination of the not connected set shows large objects.
- Use large objects sparingly and reuse them when possible.
- Beware of methods which may inadvertently create large objects.
- WriteStream>>contents is one such method.
The Fruit of Failure: Unsuccessful Commits
- Part of the commit sequence involves moving the newly created objects to be committed from LOM onto pages in the gem’s private page cache.
- If the commit is successful, these objects will be also moved into the shared page cache as part of the commit processing.
- However, if the commit fails, the objects cannot be moved to the shared cache and must remain in the private page cache. These objects then become members of the not connected set.
- Look for a correlation between failed commits and the not connected set size. If the not connected set size increases shortly after a failed commit, new LOM objects which cannot be committed are being placed in the not-connected set.
- Not all failed commits will produce a large number of not-connected objects. Only transactions which create many new objects will cause this behavior. Failed transactions which modify many committed objects will not have this problem.
- Eliminate commit failures. This is a desirable objective for other reasons beyond not-connected object considerations. Commit failures usually occur because of flaws in the application’s transaction model.
- Consider manually running the NCGC after a commit failure to remove as many objects as possible from the NC set before the next successful commit. This should probably be done after an abort.
Guilty By Affiliation: LOM Objects Referenced by Not Connected Objects
- Not-connected objects may reference objects in LOM.
- During a commit, all objects in LOM which are referenced by an object in POM (including NC objects) are moved out of LOM onto a page.
- Therefore, a NC object which references objects in LOM can cause the NC set to grow at commit time.
- Let object 401 be an array which is a large object. This object will reside in the not connected set.
- Let object 2 be an Association which resides in LOM.
- Object 2 (the association) is now added to Object 1 (the array), as shown in the following figures.
- Look for an increase in the not connected set size that correlates to commits by the gem.
- Consider manually running the NCGC before the commit if it will remove the collection from the NC set.
- Connect the collection to the repository and commit so that it will be removed from the NC set. There is no harm in doing this because the collection object will be written to disk anyway if the gem ever commits with it present in the NC set.
category: 'Private-GS Consulting Extensions' method: Object isLarge "Created By: Norman R. Green, GemStone Professional Services" "Test if the given object is large. Large objects are always built on a page but may not exceed 8K in physical size if they were pre-allocated to a large size but are currently empty. Example: >>Array new: 3000<< creates a large object but only consumes 28 bytes of space at creation time." | primSize page| self isSpecial ifTrue:[^false]. page := self page. ((page == 0) _or:[page == nil]) ifTrue:[^false]. primSize := self _primitiveSize. "Total number of inst vars" (primSize > 8096) ifTrue:[^true]. ((self class isBytes not) _and:[primSize > 2024]) ifTrue:[^true]. ^false %