views:

1296

answers:

4

Coming from a java background, one of the things I am used to is telling the JVM what the maximum heap size should be. If the running program tries to swallow more than is allowed, and the garbage collector cannot free any more resources, then OutOfMemoryError is thrown and it all goes bang. So setting the maximum heap size is important in Java.

Does this apply in .net? Can you set the heap size limits? Does the CLR just keep growing its heap until it reaches the machine's physical limits? Or is it not an issue in .net for some subtle reason that my Java blinkers stop me from seeing?

+6  A: 

No, it doesn't apply in .NET. The heap does indeed keep growing until it can't grow any more. (Obviously this is "after attempting to recover memory through GC, grow the heap".) Basically there isn't nearly as much tuning available in the .NET GC as in Java. You can choose the server GC or the client one, and I think there's an option for turning on/off the concurrent GC (I'll find links in a minute) but that's basically it.

EDIT: It seems there's a little more to it, although not a huge amount. Rick Minerich's blog entry on GC settings and the subsequent one seem to know rather more than I do about the matter. They're probably a good starting point for any further investigation - but they're mostly flags rather than the sort of memory limits available in JVMs.

EDIT: Pop's answer raises a good point - I've been assuming a "normal" CLR hosting model (i.e. not under your control). If you want to go to the effort of hosting it yourself, you're likely to get a lot more control - at the cost of the extra work of hosting it. I can't say I've ever looked into that side of things.

Jon Skeet
+3  A: 

You can't set max heap size in .Net unless you host the CLR yourself in a process.

Edit: To control the memory allocations of CLR including the max heap size, you need to use the hosting api to host the clr and specifically use the "Memory manager interfaces", some starter info can be found here MSDN Magazine, column CLR Inside Out : CLR Hosting APIs

Edit: to answer you question, why would you want to control the memory allocation or specifically max heap size, you usually don't want to, but if you're writing an application that is like SQL Server or IIS or some real time application then you'd have a pretty good reason to have control over memory and specifically, avoid paging, otherwise the CLR itself and the OS already do a pretty good job for you, and what is left is to ensure your that application uses minimum resources for things to work well.

Pop Catalin
Thanks - interesting information about CLR hosting. Probably overkill for what I am diong now - I will just ensure that I am not a memory hog.
serg10
Shared server environments which host multiple apps should make sure that the maximum memory allocated by all it's client apps do not overcommit the memory available. You don't want a single misbehaving app to take down the entire server because it allocates all available memory.
Kelly French
@Kelly, thats' what IIS and SQL Server do, because they are hosts for other managed apps, and they control how much memory the hosted applications are allowed to have ... on the other hand a non hosted .Net app is free to allocate as much as a native app is, no difference there (that's why in .net the hosting apis must be used to control the amount of allocated memory)
Pop Catalin
@Pop, I think that is the answer that needs more exposure. Java people are equating the CLR with the JVM which is both a boon and a bane. What we are seeing is the point when a Java coder discovers the technical/philosophical impedance between the two environments.
Kelly French
+3  A: 

You might want to look at System.Runtime.MemoryFailPoint.

leppie
Very interesting
serg10
+1  A: 

As far as I've found, there is no simple way to control the size of the heap of a .Net app using the CLR.

The link above only half answers the question. When I've researched this same issue, the response is "The heap grows to use all available memory" as if that is the only reason you'd want to control the max heap size.

On (typically Java) server environments, you don't want a badly behaving app to hog memory at the expense of other hosted apps. A simple solution is to limit the amount of memory that the app can use for it's heap. This is accomplished with Java's -Xmx argument so you can guarantee the app won't use more than what is planned, e.g. -Xmx256M. Since allocating memory on the heap during initialization can slow the apps startup, Java uses the -Xms arg to allow apps that do alot of object creation during initialization to start out with a large block of heap instead of the JVM contantly resizing the heap as it goes.

.Net's CLR does not have this ability. I suspect it is because .Net's CLR is not a virtual machine. The CLR happens to be an API (quite comprehensive, I might add) which serves as an adapter to native .dlls which equate to an approach much more like an executable when it comes to memory management.

I've asked this question about SharePoint development and did hear that it might be possible to control the heapsize through the use of IIS modules called Web Apps whereby you can tell IIS to limit the memory of a given web app. I wonder if this is because IIS has customized routines which replace/override new()/malloc()/etc and thus can provide this type of control to client apps. That means that standalone .Net apps are out of luck unless you want to write a custom memory manager in C++ and create an interface for .Net

Kelly French