[Mono-dev] Few notes about finalization

Leszek Ciesielski skolima at gmail.com
Sun Dec 9 17:31:29 UTC 2012


That is a very good pattern, performance-wise, advised in multiple
MSDN articles (e.g.
http://msdn.microsoft.com/en-us/library/ms973858.aspx#highperfmanagedapps_topic7
):
extracting the finalizable resources into a single-responsibility
class visible just to it's owner and not having any other logic (and
most of all, no other outgoing references). Perhaps a Gendarme
Performance rule for this would be a good idea?

On Wed, Dec 5, 2012 at 1:14 PM, Konrad M. Kruczynski
<kkruczynski at antmicro.com> wrote:
> On śro, 2012-12-05 at 13:56 +0100, Konrad M. Kruczynski wrote:
>> Hi all,
>> it is rather known fact that adding a finalizer to the class can hurt
>> performance quite badly with generational garbage collectors. This is
>> due to the premortem finalization used by CLR. If an object is not
>> reachable during GC, but has a finalizer, it will survive and probably
>> be promoted to the next generation. Not so bad in its essence, but such
>> object will transitively make all referenced objects alive and these
>> will be promoted as well.
>>
>> Consider simple benchmark contained in the attached file Test705.cs. The
>> intstances of classes are being born and dying, also they have reference
>> to the table of objects. The class A has an finalizer. On my computer
>> (SGEN, Mono 2.10.8) the result is:
>>
>>     Took 00:00:32.4182579
>>
>> If you comment out the finalizer, the result is:
>>
>>     Took 00:00:04.2515352
>>
>> So the difference is significant.
>>
>> Most of the time (at least from my experience) developers do not need
>> premortem finalization. That is, they do not need to have the reference
>> to the instance that is being finalized. What they need is some kind of
>> simple callback called after this instance is GCd (the callback could
>> also have some kind of parameter related to such instance). As you can
>> see, this is also the case in the mentioned example -- the reference to
>> the original instance is not needed.
>>
>> When I encountered internal sgen API for reference queues, I thought
>> that this could be used to do postmortem finalization. Unfortunately,
>> the API was not stable yet and therefore not public.
>>
>> But there is another, very simple idea. Instead of having a finalizer in
>> A, one could do dummy class B (with its own finalizer) to instance of
>> which A would have a reference. Therefore B's finalizer would serve as a
>> callback function of A.
>>
>> The attached example Test706.cs is based on this idea. And the result
>> is:
>>
>>     Took 00:00:04.6424758
>>
>> So it is in the same order of magnitude.
>>
>> Yup, this is very simple idea, nonetheless works well and did not come
>> to me as a solution immediately, so maybe this will be useful to
>> someone. Or I am wrong somewhere ;)
>>
>> --
>
> It may be worth adding, that with the fresh Mono from GIT the results
> are similar (although new sgen is faster in general which is a good
> news), respectively:
>
> Took 00:00:28.1762050
> Took 00:00:03.5601241
> Took 00:00:03.9642138
>
> --
> Konrad
>
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list


More information about the Mono-devel-list mailing list