Android GC.WaitForPendingFinalizers() causing freeze

Hi, during testing my monogame project, I found out that when I run

GC.Collect();
GC.WaitForPendingFinalizers();

My app freezes.

The strange thing is, if I build & run my app in Debug mode(with Samsung Galaxy S6) it freezes, but if I build & run my app in Release mode, it’s OK.

Here’s log just before the app freezes :

07-03 05:02:32.123 I/art     (23172): Starting a blocking GC Explicit
07-03 05:02:32.140 I/art     (23172): Explicit concurrent mark sweep GC freed 876(45KB) AllocSpace objects, 4(336KB) LOS objects, 33% free, 32MB/48MB, paused 154us total 16.590ms
07-03 05:02:32.140 D/Mono    (23172): GC_TAR_BRIDGE bridges 19 objects 21 opaque 0 colors 19 colors-bridged 19 colors-visible 19 xref 0 cache-hit 0 cache-semihit 0 cache-miss 0 setup 0.02ms tarjan 0.02ms scc-setup 0.02ms gather-xref 0.00ms xref-setup 0.00ms cleanup 0.02ms
07-03 05:02:32.140 D/Mono    (23172): GC_BRIDGE: Complete, was running for 17.15ms
07-03 05:02:32.140 D/Mono    (23172): GC_MAJOR: (user request) time 3.40ms, stw 3.82ms los size: 2052K in use: 1091K
07-03 05:02:32.140 D/Mono    (23172): GC_MAJOR_SWEEP: major size: 1184K in use: 309K
07-03 05:02:55.239 D/Mono    (23172): [0xbdf8c920] worker finishing
Thread finished: <Thread Pool> #7
InspectorDebugSession(7): HandleTargetEvent: ThreadStopped
The thread 'Unknown' (0x7) has exited with code 0 (0x0).

What am I doing wrong here?

I’ve been narrowing down this problem the whole day and found out when this happens.

protected override void LoadContent()
{
	// Create a new SpriteBatch, which can be used to draw textures.
	spriteBatch = new SpriteBatch(GraphicsDevice);

	    Texture2D tex = new Texture2D(GraphicsDevice, 2, 2);
}

And then, in Update()

int frameCount = 0;		
protected override void Update(GameTime gameTime)
{	
	// TODO: Add your update logic here
	if(frameCount == 0)
	{
	    GC.Collect();
	    GC.WaitForPendingFinalizers();
        }
	base.Update(gameTime);
        frameCount++;
}

Then in frame 0, the android game freezes.

But if you call tex.Dispose() just after instantiating it, game doesn’t freeze.

One strange thing is that, in windows platform it’s OK not to call tex.dispose().

Can anyone explain what’s going on behind this strange behaviour, please?

I don’t do any android development (or ios) so this might not really apply to them, but in the .net / PC world you should never have the need to do GC.Collect() - you should leave it up to the .net framework to do the collecting when it’s needed.

Doing GC.Collect in your update could also make your game run slower as it would need to find which objects it needs to collect etc.

Disposing - it’s NOT ok to not call tex.dispose() - you should always clean up after yourself - especially if the life of tex is only for a short time in your application, If tex is there all through the life of the application - then you should still clean up and call dispose on the tex object in your Dispose() method.

With OpenGL, always always always clean up your GPU resources. Don’t let the GC finalizers try to free the unmanaged resources.

I do plan to try to fix this soon, but it is a rule that you must properly dispose of your GPU assets.

Thanks for the replies, I always used game engines and it’s my first time using frameworks.
I’ll be more careful with local variables. Thanks!