 |
|
|
Oct 18 1999. |
Large Space Problem Visualworks 2.5
|
David Wallen wrote:
>
> Hi John,
>
> A while ago we conversed about MemoryPolicy problems with
claiming that
> space was available for large arrays, when only LargeSpace
memory was
> present (which wouldn't suffice). My last email to you was
a request
> for a simple demo of the problem for presentation to the
developers,
> so that I could file a solid AR. I believe that you are
far better
> qualified to produce such an example!
>
> However, I haven't heard back from you about this. As a
result, I am
> closing this case. If you wish, this case can be reopened
at any time.
>
> Thankyou very much,
> Dave Wallen
My hurried response is below, and the problem was fixed in 3.x
Note: Change sizesAtStartup to make largespace with 2,000,000
bytes or so, aka 10x. In Show39431 note changes to uppermemory
bound and cutover for growth versus reclaim. Do it on
Show39431 new run
to create bug....
Logic as from ParcPlace Digitalk aka ObjectSpace?)
temp.im created at August 12, 1997 2:18:48 pm
Global garbage collection (please wait)...
reclaimed 0.07 Mbytes in 1.0 sec.
destroyed 0 Mbytes of garbage in PermSpace.
1.07 Mbytes free.
Hit on bad large space logic 11024296 2202804 2042680
NewRetry space logic 11024296 2202804 2042680
Hit on bad large space logic 12024296 1564344 2042680
NewRetry space logic 12024296 1564344 2042680
Hit on bad large space logic 12024296 753960 2045208
NewRetry space logic 12024296 753960 2042136
At this point we get the emergency notifier saying it cannot
allocate the object and we halt...
Note Dynamic allocated footprpint is only 12024296 bytes, freespace
in OldSpace is 753868, but LargeSpace still has 2042136. But
an OrderedCollection cannot live in LargeSpace? Given mistake
in logic MemoryPolicy does not force a grow but it could since
dynamic footprint is below 20MB upperMemory bound.
Below is behavior after logic change to ignore largespace in
MemoryPolicy>>makeSpaceFor: as you can see the image grows
to a dynamically allocated footprint of 19,994,296 bytes or 8MB
bigger than before.
Global garbage collection (please wait)...
reclaimed 0.03 Mbytes in 3.8 sec.
destroyed 0 Mbytes of garbage in PermSpace.
4.05 Mbytes free.
Hit on bad large space logic 12024296 728468 2039376
NewRetry space logic 13024296 1728468 2039376
Hit on bad large space logic 13024296 909664 2042448
NewRetry space logic 14024296 1909664 2042448
Hit on bad large space logic 14024296 1090440 2042448
NewRetry space logic 15024296 2090440 2042448
Hit on bad large space logic 15024296 1271216 2038732
NewRetry space logic 16024296 2271216 2038732
Hit on bad large space logic 16024296 1451992 2042112
NewRetry space logic 17024296 2451992 2042112
Hit on bad large space logic 17024296 1632768 2042112
NewRetry space logic 18024296 2632768 2042112
Hit on bad large space logic 18024296 1813544 2042112
NewRetry space logic 19024296 2813544 2038024
Hit on bad large space logic 19024296 1994320 2041740
NewRetry space logic 19994296 2964320 2041740
Hit on bad large space logic 19994296 2145096 2041740
NewRetry space logic 19994296 2145096 2041740
'From VisualWorks(R), Release
2.5 of September 26, 1995 on August 12,
1997 at 2:20:56 pm'!
Object subclass: #Show39431
instanceVariableNames: 'muchMoreMemoryThanICanUseToday size '
classVariableNames: ''
poolDictionaries: ''
category: '**Hierarchy**'!
!Show39431 methodsFor: 'initialize-release'!
initialize
" ObjectMemory sizesAtStartup: #(1.0 1.0 10.0 1.0 1.0 1.0)"
ObjectMemory verboseGlobalCompactingGC.
size := 10000.
muchMoreMemoryThanICanUseToday := OrderedCollection new: size.
ObjectMemory currentMemoryPolicy growthRegimeUpperBound: 12000000.
ObjectMemory currentMemoryPolicy memoryUpperBound: 20000000!
!
!Show39431 methodsFor: 'process'!
run
size timesRepeat: [muchMoreMemoryThanICanUseToday add:
(OrderedCollection new: 204800)]! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
Show39431 class
instanceVariableNames: ''!
!Show39431 class methodsFor: 'instance creation'!
new
^super new initialize! !
!Behavior methodsFor: 'private'!
handleFailedNew: error size: newSize
"Called if the #new: primitive fails. This primitive can
fail for
one of three reasons:
1. The class is not indexable
2. The argument is not a positive integer
3. There is insufficient memory to perform the allocation.
In the first two cases, raise an error. In the latter case,
attempt to make additional space
and try again. If successful,
this method answers with a new
instance of the receiver (a class)
with the number of indexable variables
specified by the argument, anInteger."
error name == #'allocation failed'
ifTrue:
[error handleErrorFor: self.
Transcript show: 'NewRetry space logic';
space;
show: (ObjectMemory dynamicallyAllocatedFootprint printString);
space;
show: (ObjectMemory current availableFreeBytes printString);
space;
show: (ObjectMemory current largeBytes - ObjectMemory current
largeUsedBytes) printString; cr.
^self newNoRetry: newSize].
error name == #'inappropriate operation'
ifTrue:
[^self error: 'This class does not support variable sized
allocations'].
error name == #'bad argument'
ifTrue:
[^self error: 'This message needs a positive integer argument'].
self error: 'Unexpected error'! !
!MemoryPolicy methodsFor: 'growing memory'!
makeSpaceFor: bytesNeeded
"Attempt to make space for an object allocation of amount
bytes,
growing memory if needed."
| bytesWanted grewMemory reserveBytes largeChunk smallChunk
largeChunkFound smallChunkFound |
grewMemory := largeChunkFound := smallChunkFound := false.
bytesWanted := bytesNeeded + (bytesNeeded // 100). "1% headroom,
if
possible"
"Try to grow if we are biased towards growing."
self favorGrowthOverReclamation ifTrue:
[grewMemory := self growMemoryByAtLeast: bytesWanted].
"Try to free up memory if necessary."
grewMemory ifFalse:
[ObjectMemory garbageCollect].
"Confirm that we have freed up enough space."
(memoryStatus edenBytes - memoryStatus edenUsedBytes) > bytesWanted
ifTrue: [^self].
(memoryStatus largeBytes - memoryStatus largeUsedBytes) >
(bytesWanted
+ memoryStatus bytesPerLTE) ifTrue:
[Transcript show: 'Hit on bad large space logic';
space;
show: (ObjectMemory dynamicallyAllocatedFootprint printString);
space;
show: (ObjectMemory current availableFreeBytes printString);
space;
show: (ObjectMemory current largeBytes - ObjectMemory current
largeUsedBytes) printString; cr.
^self].
reserveBytes := memoryStatus reservedContiguousFreeBytes.
bytesWanted < reserveBytes
ifTrue: [largeChunk := reserveBytes. smallChunk := bytesWanted]
ifFalse: [largeChunk := bytesWanted. smallChunk := reserveBytes].
1 to: memoryStatus oldSegments do: [:seg | | freeBytesInSeg |
freeBytesInSeg := memoryStatus contiguousSpaceAt: seg.
largeChunkFound ifFalse:
[freeBytesInSeg >= largeChunk ifTrue:
[freeBytesInSeg := freeBytesInSeg - largeChunk.
largeChunkFound := true]].
smallChunkFound ifFalse:
[freeBytesInSeg >= smallChunk ifTrue:
[smallChunkFound := true]].
(largeChunkFound and: [smallChunkFound]) ifTrue: [^self]].
"No room anywhere, attempt a last-ditch grow."
(self growMemoryByAtLeast: bytesWanted)
ifFalse: [self growMemoryByAtLeast: bytesNeeded].! !
|