GC Functionality in TinyCLR OS

Several people have mentioned microPython on this forum and I started checking it out. I’m not going to dump C# anytime soon but it does have some nice functionality controlling the garbage collector. I’ve been successful at using think .Net Micro in real time applications on the order of tenths or even hundredths of a second as long as I can keep the GC from running. I can do that by 1) being careful about where I use the new operator and 2) Never using string operations anywhere I need real time response. But it sure would be easier if I had the functionality that microPython provides to control the GC.

Here’s the link to the documentation

http://docs.micropython.org/en/v1.9.3/pyboard/library/gc.html

and here’s a summary of the functionality:

gc – control the garbage collector

Functions
gc.enable(): Enable automatic garbage collection.

gc.disable(): Disable automatic garbage collection. Heap memory can still be allocated, and garbage collection can still be initiated manually using gc.collect().

gc.collect(): Run a garbage collection.

gc.mem_alloc() Return the number of bytes of heap RAM that are allocated.

gc.mem_free() Return the number of bytes of available heap RAM, or -1 if this amount is not known.

gc.threshold([amount]) Set or query the additional GC allocation threshold. Normally, a collection is triggered only when a new allocation cannot be satisfied, i.e. on an out-of-memory (OOM) condition. If this function is called, in addition to OOM, a collection will be triggered each time after amount bytes have been allocated (in total, since the previous time such an amount of bytes have been allocated). amount is usually specified as less than the full heap size, with the intention to trigger a collection earlier than when the heap becomes exhausted, and in the hope that an early collection will prevent excessive memory fragmentation. This is a heuristic measure, the effect of which will vary from application to application, as well as the optimal value of the amount parameter.

Does TinyCLR support the GC.TryStartNoGCRegion/GC.EndNoGCRegion Methods?

(I’m at work and can’t check)

They’ve been in .net since 4.6 - they should be useful for those concerns.

1 Like

We don’t currently support TryStartNoGCRegion and EndNoGCRegion, but that is something we have been looking into adding.

Enable and Disable are also something we could look into adding if the above aren’t enough. You’ll still be able to allocate, but if you run out of memory, either due to exhaustion or fragmentation, you’ll get an exception.

mem_alloc should currently be available as GC.GetTotalMemory(). mem_free is something we’d like to add back but haven’t yet found a place for it.

Keep in mind that GC in NETMF and TinyCLR doesn’t run randomly. It should only be triggered by an allocation that can’t be satisfied, so proper structuring of your program can avoid a lot or all of it. As you pointed out yourself, string operations are particularly tricky. The new functionality in big .NET around ref struct and Span<T> may be really useful here going forward.

Thanks for the information. For my apps, GC.GetTotalMemory, and GC.Enable/Disable are the critical functions. .GetTotalMemory so I can make sure I know if/where/where not my app is creating garbage and Enable/Disable to protect the real time sections of my code. NoGCRegion doesn’t sound like the right functionality for my apps since the real time section I’m trying to protect is usually a state machine spread over many classes so there isn’t one specific chunk of code I can point to where I want to prevent GC. Sounds like you guys are working on it.