MikePopoloski / SharpBgfx

C# bindings for the bgfx graphics library
MIT License
169 stars 30 forks source link

Free unmanaged memory from objects finalizer #24

Closed Alan-FGR closed 6 years ago

Alan-FGR commented 6 years ago

Hello there.

Some objects like for example the VertexBuffer that are responsible for unmanaged resources implement IDisposable what allows you to release unmanaged memory by calling Dispose(). The problem is if the user forgets to do that the GC will destroy the object and the unmanaged memory will leak. An easy solution to that is to simply free the unmanaged resources from the finalizer and then suppress it in the Dispose() implementation, so the user still has full control to deterministically free the unmanaged memory, while the program will also be safe: in case the user doesn't do that the finalizer will. Finalizers run on a separate thread though.

Another question is regarding MemoryBlock. I understand that when you pass that memory to BGFX objects they're responsible for freeing it, but if you are just preparing some memory and never uses it, there should be a way to free that imho. This is just something I caught randomly as I only use the ptr ctor in my code (and I alloc mem in unmanaged heap from C#).

Alan-FGR commented 6 years ago

Oh well... I just realized that if you free the unmanaged resources in the finalizer and you lose the reference they'll be freed and BGFX might still have to access that data.

MikePopoloski commented 6 years ago

Finalizers have far too many problems to rely on them for real resource management.

As far as the MemoryBlock goes, it calls into the native API to allocate the memory, which does not have a corresponding free. The only option is to not allocate the memory block unless you're going to use it.

Alan-FGR commented 6 years ago

True. My concern is mostly when the user forgets to manually dispose the unmanaged resource, for those situations I normally use a debug-guarded finalizer that checks whether the resource was freed when the object was collected. The problem with finalizers imho is that there's no way to inform the GC of how much time a finalizer is expected to run although freeing is generally pretty fast.