While trying to fix some things in pharo I came across a test
I have some problems with understanding (by the way this test has vanished in 3.10). testFinalizationOfEquals "self debug: #testFinalizationOfEquals" | bag o | bag := IdentityBag new. 1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend: #remove: to: bag with: n]. 1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend: #remove: to: bag with: n]. o := nil. "<-- Hello Klaus :)" Smalltalk garbageCollect. self assert: [ bag isEmpty ]. My problem is that toFinalizeSend:to:with adds an Objectfinalizer to the finalizationRegistry of the instance. But Object>>finalizationRegistry "Answer the finalization registry associated with the receiver." ^WeakRegistry default returns a global object which is WeakKeyDictionary. And | d | d := WeakKeyDictionary new. d at: (1 asString copy) put: $a. d at: (1 asString copy) put: $b. d size prints 1. To me that would exchange every entry from the first run by the second run (because the objects are equal). So I would assume that if there does not happen a run of the garbagecollector between the two loops the objects of the first loop should be still contained in the bag. But the test is named finalizationOfEquals so I have to assume: self doesNotUnderstand Can someone explain it to me, please? Norbert |
On Jun 14, 2008, at 12:29 , Norbert Hartl wrote: > While trying to fix some things in pharo I came across a test > I have some problems with understanding (by the way this test has > vanished in 3.10). > > testFinalizationOfEquals > "self debug: #testFinalizationOfEquals" > > | bag o | > bag := IdentityBag new. > 1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend: > #remove: to: bag with: n]. > 1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend: > #remove: to: bag with: n]. > o := nil. "<-- Hello Klaus :)" > Smalltalk garbageCollect. > self assert: [ bag isEmpty ]. just for clarification, the original version of the test used *equal* values (as the test name suggests): bag := IdentityBag new. 1 to: 5 do: [:n | o := n asString copy. bag add: n. o toFinalizeSend: #remove: to: bag with: n]. 1 to: 5 do: [:n | o := n asString copy. bag add: n. o toFinalizeSend: #remove: to: bag with: n]. Smalltalk garbageCollect. 1 to: 5 do: [:n | self deny: (bag includes: n)] I guess, this test has been added to point out that the finalization mechanism does not correctly work when used concurrently with objects that are equal. The finalization registry uses a WeakKeyDictionary, rather than a WeakIdentityKeyDictionary, as Norbert notes below, thats why... What was the rationale to remove this test in 3.10? Is this an expected behavior? Adrian > > > My problem is that toFinalizeSend:to:with adds an Objectfinalizer > to the finalizationRegistry of the instance. But > > Object>>finalizationRegistry > "Answer the finalization registry associated with the receiver." > ^WeakRegistry default > > returns a global object which is WeakKeyDictionary. And > > | d | > d := WeakKeyDictionary new. > d at: (1 asString copy) put: $a. > d at: (1 asString copy) put: $b. > d size > > prints 1. To me that would exchange every entry from the first > run by the second run (because the objects are equal). > > So I would assume that if there does not happen a run of the > garbagecollector between the two loops the objects of the first > loop should be still contained in the bag. But the test is named > finalizationOfEquals so I have to assume: self doesNotUnderstand > > Can someone explain it to me, please? > > Norbert > > > |
On Sat, 2008-06-14 at 14:33 +0200, Adrian Lienhard wrote:
> On Jun 14, 2008, at 12:29 , Norbert Hartl wrote: > > > While trying to fix some things in pharo I came across a test > > I have some problems with understanding (by the way this test has > > vanished in 3.10). > > > > testFinalizationOfEquals > > "self debug: #testFinalizationOfEquals" > > > > | bag o | > > bag := IdentityBag new. > > 1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend: > > #remove: to: bag with: n]. > > 1 to: 5 do: [:n | o := Object new. bag add: n. o toFinalizeSend: > > #remove: to: bag with: n]. > > o := nil. "<-- Hello Klaus :)" > > Smalltalk garbageCollect. > > self assert: [ bag isEmpty ]. > the test is green :) thanks, Norbert > just for clarification, the original version of the test used *equal* > values (as the test name suggests): > > bag := IdentityBag new. > 1 to: 5 do: [:n | o := n asString copy. bag add: n. o toFinalizeSend: > #remove: to: bag with: n]. > 1 to: 5 do: [:n | o := n asString copy. bag add: n. o toFinalizeSend: > #remove: to: bag with: n]. > Smalltalk garbageCollect. > 1 to: 5 do: [:n | self deny: (bag includes: n)] > > I guess, this test has been added to point out that the finalization > mechanism does not correctly work when used concurrently with objects > that are equal. The finalization registry uses a WeakKeyDictionary, > rather than a WeakIdentityKeyDictionary, as Norbert notes below, thats > why... > > What was the rationale to remove this test in 3.10? Is this an > expected behavior? > > Adrian > > > > > > > My problem is that toFinalizeSend:to:with adds an Objectfinalizer > > to the finalizationRegistry of the instance. But > > > > Object>>finalizationRegistry > > "Answer the finalization registry associated with the receiver." > > ^WeakRegistry default > > > > returns a global object which is WeakKeyDictionary. And > > > > | d | > > d := WeakKeyDictionary new. > > d at: (1 asString copy) put: $a. > > d at: (1 asString copy) put: $b. > > d size > > > > prints 1. To me that would exchange every entry from the first > > run by the second run (because the objects are equal). > > > > So I would assume that if there does not happen a run of the > > garbagecollector between the two loops the objects of the first > > loop should be still contained in the bag. But the test is named > > finalizationOfEquals so I have to assume: self doesNotUnderstand > > > > Can someone explain it to me, please? > > > > Norbert > > > > > > > > |
Free forum by Nabble | Edit this page |