This entry was posted on Thursday, December 20th, 2007 at 12:47 pm and is filed under FAQ. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
How big should the cache be?
Q: “I created 10,000 objects in one transaction and then updated all of them in another transaction. How big can I make the cache?”
A: For performance reasons it’s important to set the maximum cache size big enough to accommodate the number of objects in your largest transaction. The reason for this is that whilst the cache will always expand, even beyond its set maximum size, to hold all the objects in all the currently open transactions, whilst it is larger than the max size it is significantly slower. This is because each time an object is added to the cache, when at its max size, it searches for the least recently used unlocked object (not included in any transaction) and removes it; this is a linear search from the tail end of the cache and is thus long and fruitless when there are no unlocked objects left in it.
The cache can be set to any size compatible with available physical memory; the memory occupied is displayed in the Control Panel when ByteSizeCalculation is enabled, though in normal use this should be disabled because the calculation takes time.
If the first transaction after log-on virtualizes 10000 objects there will be a lot of disk activity; this is because the pre-allocation cache (pac) is initialized to 25 new objects and when these have all been allocated during the growing (application-in-control) phase of a transaction, subsequent new virtualizations require disk writes and therefore file flushing to maintain file integrity. Whenever a transaction commits after having had to create new virtual objects in excess of the pac size it remembers this and expands the pac by this number as part of the transaction commit, so the next transaction to create 10000 new objects will be able to get them all from the pac, saving all that disk activity. Unallocated objects still in the pac at log-off are discarded, i.e. they become instant garbage, which is harmless.
This excessive disk activity on the first transaction can be avoided by a pac initialization transaction after log-on and before the first big application transaction, in order to grow the pac within the scope of one transaction flush instead of 10000 flushes, like this:
| vom customers departments |
[ vom := VOManager newForExistingSpace: ‘c:\vospaces\myspace’.
vom isNil ifTrue: [^self].
vom open ifFalse: [^self].
vom cacheMaxSize: 11000.
vom storageManager pacSize: 10000 “set required pac size”.
[Array newVirtualIn: vom] atomic. “dummy transaction to trigger pac growth”
[ customers := vom rootDictionary at: ‘customers’.
departments := vom rootDictionary at: ‘departments’
] atomicReadOnly.
…
…
…
] forkAt: (Processor userBackgroundPriority).
Leave a Reply
