[Vm-dev] Re: Too many full GCs in Cog/Spur ... while just drawing GUI ...

Levente Uzonyi leves at caesar.elte.hu
Fri Apr 8 16:29:48 UTC 2016


On Fri, 8 Apr 2016, Bert Freudenberg wrote:
>
> On 08.04.2016, at 00:34, Levente Uzonyi <leves at caesar.elte.hu> wrote:
> >
> > When the VM runs out of memory primitive 71 in #basicNew: will fail and it'll send
> > #handleFailingBasicNew:. That method will retry primitive 71, which will fail again, and then it'll do a full gc to make room for the new
> object.
>
> I couldn’t believe regular GC would go through primitive failure code and rely on the image to invoke a full GC.

It does. Perhaps it's worth trying #garbageCollectMost before doing a full 
GC. It decreases the full GC significantly in cases when larger objects 
are allocated and thrown away frequently.

I had replaced

 	Smalltalk garbageCollect < bytesRequested ifTrue:
 		[Smalltalk growMemoryByAtLeast: bytesRequested].

with

 	Smalltalk garbageCollectMost < bytesRequested ifTrue:
 		[Smalltalk garbageCollect < bytesRequested ifTrue:
 			[Smalltalk growMemoryByAtLeast: bytesRequested]].

in #handleFailingBasicNew: and the number of full GCs has never gone above 
4 when running this snippet:

Smalltalk garbageCollect.
x := Smalltalk vmParameterAt: 7. "num full GC since startup"
{ [ActiveWorld imageForm] bench.
(Smalltalk vmParameterAt: 7) - x }

Doing the same trick in #handleFailingBasicNew has taken the number down 
to 2.
So I suggest we should use both changes if it has no negative side 
effects. Eliot? :)

>
> And in fact, it doesn’t. I put a "BasicNewFailures := BasicNewFailures + 
1.” in basicNew(:) and it never increased. So I think this is invoked
> only in severe conditions.

Try the snippet above. The way I found this was that I also had the #bench 
send wrapped in #timeProfile, so it appeared in the profiler. Make sure 
you have only a few windows open, otherwise drawing will take way too 
long and there won't be enough allocations to trigger the failure.

>
> > Only when it's not possible to make room for the new object by collecting the garbage will the VM allocate more memory.
>
> I see that code in Behavior (calling growMemoryByAtLeast:), yes, but in my tests it never got invoked.
>
> > Forcing the VM to allocate more memory, by tweaking parameter 25, will decrease the number of GCs, though I wasn't able to get it down to 0,
> because the code became way too snappy and it quickly reached the new memory limit.
>
> Yes, the number of full GCs goes down. But why not to zero? I cannot understand why we cannot find a large-enough “new space size” so that the
> working set is fully kept in there. Redrawing a couple windows should not produce any long-lived objects that trigger a full GC every second.
>

If you replace #bench with #benchFor: 1 seconds, then the number of full 
GCs will stay zero (using the #garbageCollectMost change I suggested 
above).

Levente


More information about the Vm-dev mailing list