[codesyntax lang=”smalltalk”]
!VirtualMachineExe methods !
oldSpaceBytesTotal
| min max oldSpaceInfo |
oldSpaceInfo := ( ExternalBuffer atAddress: ( ( VirtualMachineLibrary queryProcAddr: 'ObjectStore' ) + 48) ).
min := oldSpaceInfo addressAtOffset: 16.
max := oldSpaceInfo addressAtOffset: 20.
^max asInteger - min asInteger! !
Object subclass: #ProcessScheduler
instanceVariableNames:
' readyProcesses bytesCollected bytesFlipped oldSpacePages newSpacePages newSpaceLimit gcOperation traceMode bytesTenured unboundComponents oldSpaceThreshold inTrouble inPanic '
classVariableNames:
' Finalizer GCStrategy OldSpaceThresholdIncrement '
poolDictionaries: '' !
!ProcessScheduler methods !
gcStrategy
" Answer the strategy for doing global compacts. "
^GCStrategy!
gcStrategy: aSymbolOrNil
" Set the strategy for doing global compacts:
aSymbolOrNil may be:
nil - the digitalk default (1MB)
#fixed - a fixed percentage of oldSpaceTotal
#adaptive - a fixed percentage of oldSpaceAvailable"
GCStrategy := aSymbolOrNil.!
oldSpaceBytesAvailable
" Answer the amount of memory that can be allocated for old space in bytes "
^self oldSpaceBytesTotal - self oldSpaceBytesUsed!
oldSpaceBytesTotal
" Answer the maximum amount of memory for old space currently configured in bytes "
^VirtualMachineExe current oldSpaceBytesTotal!
oldSpaceBytesUsed
" Answer the amount of memory currently used for old space in bytes "
^self oldSpacePages * 4096!
oldSpaceThresholdAdaptive
" Answer the threshold increment for the process scheduler.
We take 10% of the free old space size and round it towards the next 1 MB boundary.
To configure the process scheduler we must answer a number of CPU pages (4096 bytes each) "
^(((self oldSpaceBytesAvailable // 10) + 524288 ) bitAnd: 16rFFF00000) / 4096!
oldSpaceThresholdDigitalk
" the default used by Digitalk - answer the number of CPU pages (4096 bytes each) "
^self oldSpaceThresholdIncrement!
oldSpaceThresholdDynamic
" Answer the value for oldSpaceThreshold depending on the chosen strategy. "
| s |
(s := self gcStrategy) == #fixed ifTrue: [ ^self oldSpaceThresholdFixed ].
s == #adaptive ifTrue: [ ^self oldSpaceThresholdAdaptive ].
^self oldSpaceThresholdDigitalk!
oldSpaceThresholdFixed
" Answer the threshold increment for the process scheduler.
We take 1% of the old space size and round it towards the next 1 MB boundary.
To configure the process scheduler we must answer a number of CPU pages (4096 bytes each) "
^(((self oldSpaceBytesTotal // 100) + 524288 ) bitAnd: 16rFFF00000) / 4096!
rebalance
"Private - If oldSpace is too large, do a compact."
| increment |
unboundComponents isNil ifTrue: [
unboundComponents := SmalltalkLibraryBinder unboundK ].
SmalltalkLibraryBinder unboundK > ( unboundComponents + 1000 ) ifTrue: [
"some libs were unbound since last time, so try to free them."
unboundComponents := SmalltalkLibraryBinder unboundK.
SmalltalkLibraryBinder compact.
unboundComponents := SmalltalkLibraryBinder unboundK ].
increment := self oldSpaceThresholdDynamic.
oldSpacePages > oldSpaceThreshold
ifTrue: [
oldSpaceThreshold := oldSpacePages + 10.
SmalltalkLibraryBinder unboundCount > 0
ifTrue: [ SmalltalkLibraryBinder compact ]
ifFalse: [ Smalltalk unusedMemory ].
self status.
oldSpaceThreshold := oldSpacePages + increment.
self configure
].
oldSpaceThreshold > (oldSpacePages + increment)
ifTrue: [
oldSpaceThreshold := oldSpacePages + increment.
self configure
].!
[/codesyntax]