6

I need to force Terminal servers using Dynamic RAM to provide MORE RAM to my lean running .NET application and thus reduce .NET GC RAM pressure and increase performance.

For my large Microsoft .NET C# WinForms application compiled using X86 as the target, is there a Garbage collector or other .NET Framework setting available to allow my application to use more RAM to increase performance instead of letting the .NET Garbage collector try to keep RAM pressure under control so tightly?

I'm hoping for some .NET GC hint, setting or .NET framework function call to adjust how lean it runs.

Reason: My application is used by tens of thousands of users across thousands of terminal servers every workday for the duration of their business hours. Over a 15 year deployment period I've found the application will perform adequately when provided with about 1.85GB of RAM per instance.

We have done SIGNIFICANT development to ensure minimum RAM usage and memory leaks are kept under control. (IE: Using(){}, Calling Dispose on Every object possible among other things)

However this is a Huge application accomplishing nearly every task for client business operations including some graphics and much more and I expect large RAM usage.

I cannot change to 64-bit until we remove old 3rd party GUI controls which will take months of development and management will not let me scheduled that because it will not provide any direct end user upgrades. (Except overall better performance....)

The problem is convincing the client's IT companies which host the terminal servers to add the required RAM to maintain performance. Their typical argument is that the Virtual Machines do not report heavy RAM usage, which instantly means I need to spend days convincing them that is not the best metric to use in this case.

Also for servers where dynamic RAM is used and the application performance is reduced without growing the OS RAM properly.

My goal is to adjust some setting to allow more RAM usage (NOT using unneeded/fake Memory consumption) and push those servers to allocate more RAM as needed.

Moon
  • 1,141
  • 2
  • 11
  • 25
  • You can't use more memory than what you have on the PC. Windows will use the hard drive to swap memory (cache) when you use more memory than what the computer actually has, but using the swap significantly slows down an application. I would use Control Panel to see ow much cache is being used. – jdweng Jul 19 '17 at 21:47
  • It's not, but .NET GC Keeps the Memory usage at around 40% of the available RAM. Thus the IT says "your not using the RAM" Only when more RAM is added to the HOST does the .NET GC open up, uses more RAM and the application performs better. I want to approach closer to the 100% usage by default. – Moon Jul 19 '17 at 21:51
  • You may give the proposed solution here a try; https://stackoverflow.com/questions/1075542/configure-net-clr-ram-usage though I personally think you're pretty much out of luck. Perhaps putting that settings a 2GB or something would cause the OS to try and use more RAM and the services managing the VM's in turn to allocate that RAM. But unless the VM literally has no RAM left, why would it scale so you have more RAM? And why would Windows allow you to set the CLR's RAM usage at a value higher than the RAM it believes itself to have? – evanmcdonnal Jul 19 '17 at 21:51
  • https://stackoverflow.com/questions/14186256/net-out-of-memory-exception-used-1-3gb-but-have-16gb-installed https://stackoverflow.com/questions/2597790/can-i-set-largeaddressaware-from-within-visual-studio – George Vovos Dec 04 '18 at 11:07
  • As per my understanding by design x86 process cannot have more than 2GB ram for usage, I would suggest, if possible, break down your application into multiple processes (similar to what web browsers do) to overcome that limit if needed. – Dipen Shah Dec 04 '18 at 16:29
  • You are not making much sense.... or its really hard to understand what you are trying to say. Dynamic RAM? link plz, as i hope you are not just talking about regular memory, I feel by reading this that you haven't got a firm grip on whats going on. lots going on here... Terminal servers, i take it your app is running on this... how many Terminal sessions at once? how much ram does ur app consume... do the diff and see what you max is, while maintaining enough ram for all clients. how much ram does each Terminal session take without your app. – Seabizkit Dec 06 '18 at 12:58
  • 1
    is the Terminal server x86 as well? – Seabizkit Dec 06 '18 at 13:01
  • 1
    If the Terminal servier is x64, you can devide your application into many services that are x64 while keeping the application on x86. The other option to go with is to use stored cache, which can be stored on SSD, HDD or Intel's Optane memory optionally. – NagyDani Dec 07 '18 at 15:27
  • https://downloadmoreram.com/ – eselskas Dec 10 '18 at 17:47

1 Answers1

14

But .NET GC Keeps the Memory usage at around 40% of the available RAM

There are several misconceptions in this question and its comments, this is a core one. The GC and the CLR are completely oblivious to RAM, much like any program that runs on a modern demand-paged virtual memory operating system. "virtual" is a key term, the OS creates the illusion that a process has access to all the address space that a processor can provide. 2GB for a 32-bit process, many terabytes for a 64-bit process.

The "demand-paged" is the other key term, the OS provides RAM to a process with a unit of pages, 4096 bytes at a time. On demand, not when it is allocated but when the process reads or writes from an address. The paging file is a key OS resource, that is where memory content is stored when not enough RAM is available. RAM content is paged-out when the OS needs to provide RAM pages for other processes. Paged back in on demand by a page fault.

On a machine with a low amount of RAM, these page faults can happen frequently and can noticeably slow down a program. Visible in Task Manager, you can add a column for "PF Delta". Other columns that are relevant is "Working set", that is the amount of RAM the program is actively using. And "Commit size", the sum of all allocations that are backed by the paging file. A .NET program increases commit size when it allocates memory.

The OS actively looks for RAM pages that have not been used for a while and pages them out. Important so it can quickly react to memory demands of other processes. If your program is the only one running on a machine then this is not very desirable. That can be tweaked, check this MSDN page for the policy. Whether that is a good idea for a terminal server is not obvious to me, I don't give it great odds, serverfault.com is the best place to ask.

Programmatically you can tinker with the Process.MinWorkingSet property, but keep in mind that the OS might ignore it when it deems the amount of available RAM to be too low. And that you might cause other processes on the server to slow down a great deal, upsetting the admin. Also something to bounce off the experts that do this every day at serverfault.com

Albert Einstein
  • 7,472
  • 8
  • 36
  • 71
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536