[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]