2

I would like to limit how much RAM a thread in C# can allocate, such that allocations beyond this limit will fail/crash or the thread will terminate.

So for example, suppose that I have 3 managed threads in C#, threads A, B, and C. I want to limit all three threads to not use more than 100 MB of RAM. If they do, then I want them to crash without impacting the other threads.

Now it seems to me that since C# is a virtual machine-based language, and uses a garbage collector, this should actually be theoretically possible without trying to use OS features that limit process RAM usage.

How can something like this be achieved? Any guidance would be greatly appreciated.

A X
  • 905
  • 2
  • 13
  • 31
  • While accepted answer is right, you could play with `GC.GetAllocatedBytesForCurrentThread` and stop the thread by yourself if given threshold is exceeded. – Konrad Kokosa Oct 24 '22 at 08:01

1 Answers1

5

You can't limit the RAM used by a thread, or a group of threads, because the only RAM that is owned by a thread is its stack (around 1MB of memory). The memory that is allocated in the heap is shared by all threads of the program. It's not owned by any thread or groups of threads. There is no provision in the C# language or the .NET runtime for preventing a specific thread from interacting with an object allocated in the heap. If you want to limit the amount of RAM that is available for an operation, you must isolate this operation in a separate process, not a separate thread.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
  • 1
    Thanks for the great answer. As a general observation, I think that this is very unfortunate. I feel that we really need more granular control. Ideally the garbage collector should be instantiatable per thread, instead of only per process. The fact that it is virtualized should make this easier than in the managed code world. Features like this are critical for building heavy infrastructure systems. – A X Oct 23 '22 at 19:11
  • @AX I don't think that this functionality can be retrofitted in .NET in a pay-for-play fashion. You would have to stuff all objects with thread-ownership information, increasing their memory footprint. You would have to check on each and every object access if the current thread has ownership of the object, and throw a runtime exception if it hasn't. You would have to increase/decrease counters on every object creation/destruction, and add memory-limit checks. That's a massive overhead, that would affect all applications, not only the few that would benefit from this functionality. – Theodor Zoulias Oct 24 '22 at 06:43