timfel / etoys-spur

A repository to track Etoys development, keep external sources, and build all-in-one bundles
MIT License
0 stars 0 forks source link

FullGC pauses become enormly long #21

Open JensLincke opened 7 years ago

JensLincke commented 7 years ago

Playing with lots of little etoys life forms results in a lot of long full GC pauses.

The image hangs so long, windows asks me to force quit the program

JensLincke commented 7 years ago

The image got bigger and bigger... up to 260 MB and growing. Closing all the projects did not help.

We looked at what was creaping around and found lots of Players and Scripts hanging around...

b := Bag new.
SystemNavigation default allObjectsDo: [:o | b add: o class theNonMetaClass].
b sortedCounts explore.

We chased some pointers:

ScriptInstantiation someInstance chasePointers

and removed the references

ScriptEditorMorph classPool at: #Evaluator put: nil
KedamaEvaluatorNodeState  initialize
HandMorph initialize "Clear PasteBuffer"

But the image did not get smaller... Full garbage collection and saving images did not help. The images does not seem to get compacted when doing a fullgc or when saving to disk?

uptime          0h31m12s
memory      273,678,336 bytes
    old         266,904,832 bytes (97.5%)
    young       4,838,224 bytes (1.8%)
    used        67,297,336 bytes (24.6%)
    free        201,470,768 bytes (73.6%)
GCs         1,221 (1533.3 ms between GCs)
    full            9 totalling 1,519 ms (0.1% uptime), avg 168.8 ms
    incr            1,212 totalling 2,118 ms (0.1% uptime), avg 1.7 ms
    tenures     529,695 (avg 0 GCs/tenure)
Since last view 1,115 (1630 ms between GCs)
    uptime      1818.1 s
    full            4 totalling 544 ms (0% uptime), avg 136 ms
    incr            1,111 totalling 1,965 ms (0.1% uptime), avg 1.8 ms
    tenures     159,741 (avg 0 GCs/tenure)

To put this to a sanity check, we wrote a script that calculated the size of the image by going over all objects:

|size|
    size := 0.
    SystemNavigation default allObjectsDo: [:o |
        (o respondsTo: #byteSize) ifTrue: [
            size := size + o byteSize   
        ] ifFalse: [        
            size := size + o class byteSizeOfInstance   
        ]
    ].
"size -> 69 839 159"

And we could only account for 70MB of the 260MB the image used on disk.

JensLincke commented 7 years ago

These scripts helped a lot... reducing my image size from 500 to 50.

(Smalltalk organization listAtCategoryNamed:  'UserObjects') do: [:name |
    Smalltalk forgetClass: (Smalltalk classNamed: name) logged: false]
Player withAllSubclasses 
    select: [:c | c isSystemDefined not]
    thenDo: [:c  | c superclass removeSubclass: c].
JensLincke commented 7 years ago

The projects were also not garbage collected...

SkObject initialize. "The class kept a reference to one project, which kept references to (all?) the others"
ReleaseBuilderSqueakland clearCaches.
timfel commented 7 years ago

A new more complete script:

Smalltalk garbageCollect.
(WeakMessageSend allInstances select: [:wm  |
    (wm receiver isKindOf: PasteUpMorph) and: [wm selector = #removeModalWindow]]) do: [:wm | wm receiver: nil].
KedamaEvaluatorNodeState initialize.
ScriptEditorMorph setDefaultEvaluator.
HandMorph initialize.
(Smalltalk organization listAtCategoryNamed:  'UserObjects') do: [:name |
    Smalltalk forgetClass: (Smalltalk classNamed: name) logged: false].
Player withAllSubclasses 
    select: [:c | c isSystemDefined not]
    thenDo: [:c  | c superclass removeSubclass: c].
SkObject initialize.
Smalltalk garbageCollect.