[Mono-dev] a set of tests to find out the difference between .Net and Mono implementation

Jonathan Pryor jonpryor at vt.edu
Tue Sep 16 16:31:37 UTC 2014


On Sep 16, 2014, at 6:10 AM, 何子杰Hzj_jie <hzj_jie at hotmail.com> wrote:
> 1. GC
> thought GC.Collect() does not guarantee all the inaccessible objects are finalized and reclaimed, .Net implementation usually be able to delete all the inaccessible objects.
> impacts, delegate_pinning_test, it make sure the delegate / event in .net will release the object after itself has been released.
> weak_pointer_test, weak_pointer is a simple wrapper of WeakReference, which is strong-typed.
> event_disposer_test, event_disposer is a strong-typed pointer, which provide disposing event when disposing.
> lifetime_binder_test, lifetime_binder is a collection to avoid the object to be finalized.

Developers need to write tests for finalizers, and writing tests for finalizers can be tricky for a variety of reasons. As such, it is quite possible that a GC-related test that "works" on .NET won't work on Mono w/o change.

If you want to test your class' finalizer, then you need to use two threads + WeakReference:

	WeakReference r = null;
	var t = new Thread (() => {
		var v = new ClassToTest ();
		r = new WeakReference (t);
	});
	t.Start ();
	t.Join ();
	GC.Collect ();
	GC.WaitForPendingFinalizers ();

	// can now [0] check r.IsAlive, etc.

The reason you create the instance + WeakReference on another thread is because Mono's GC will *conservatively* scan the thread's heap looking for valid references. By using a new thread *which exits*, the conservative stack scan will "skip" the exited thread, and thus won't find any valid references to the allocated instance. This in turn allows you to use the WeakReference to determine if the instance has in fact been collected. (Or not, if your ClassToTest registers itself with some static collection or something...)

 - Jon

[0]: https://bugzilla.xamarin.com/show_bug.cgi?id=20503



More information about the Mono-devel-list mailing list