1

Since it is recommended to use the IDisposal pattern for large objects, I am wondering, why there seems to be no reliable way to determine the limit, up from which an object is to be considered "large"?

Internally such distinction exist: the lower limit for objects being allocated on the LOH. Whenever it is communicated publicly as 85k, one at the same time is prevented from relying on that number.

Especially for applications handling a lot of "larger" arrays, that limit is necessarily needed in order to implement proper memory management and preventing LOH fragmentation. For "smaller" arrays on the other hand, IDisposal does not make sense from a memory consumption point of view. Here, the compacting GC does a lot better.

Why is there no such thing as

GC.GetLOHLimit() 

or even better:

bool GC.ArrayTargetForManualDisposal(Type type, int length); 

Edit: I know, the IDisposable pattern is just a recommendation for proper handling of special objects (f.e. "large" or unmanaged objects). My question is not assuming, there would be any special handling for those objects by the runtime. I rather ask for a runtime support for implementors of the pattern (may be others as well), to know, when an object should follow special memory management or not.

user492238
  • 4,094
  • 1
  • 20
  • 26
  • 1
    @user492238 Regarding your edit: Again, `IDisposable` has nothing to do with managed memory management. Could you please provide a reference where it is recommended that `IDisposable` be used for managing managed memory. – Tim Lloyd Jan 27 '11 at 11:01
  • IDisposable is the best way to make *sure* objects are going to be released in a pool like recommended by many resources. But the question does not rely on IDisposable. It rather asks, why there is no way to get a hint at runtime, if an object at all *needs* special handling. If that would be done inside an IDisposable or not is less important here. – user492238 Jan 27 '11 at 11:15
  • The limits are diffent for arrays of doubles – Ian Ringrose Jan 27 '11 at 11:15
  • Right. We would have to provide the type of array to the query function. – user492238 Jan 27 '11 at 11:16
  • 1
    @user492238 If you wish to reply to other user's comments, please include their @username or they will not be notified. – Tim Lloyd Jan 27 '11 at 11:22
  • @chibacity: thanks. will try to do in future. – user492238 Jan 27 '11 at 11:42

2 Answers2

4

IDisposable has no relation to managed memory management. Disposing of an object is a user convention\pattern, it is not used internally by the runtime, and has no effect on memory management. The runtime has no knowledge of IDisposable. The only special treatment\recognition of IDisposable is when used with the using keyword, but this is recognized by the compiler (at least the C# compiler), and not the runtime.

As for the LOH, there are no public guarantees with LOH algorithms - that's why there is no API to get at parameters such as maximum object size in the first place. It is quite feasible that in a future version of the CLR that object size for LOH consideration could indeed be dynamic. The CLR designers do not want users to couple themselves to internal details of memory management as this would make it harder or impossible for them to change it without breaking lots of existing programs.

If you are concerned with CLR memory-management I would first suggest getting to grips with the fact that IDisposable is not involved with it.

Tim Lloyd
  • 37,954
  • 10
  • 100
  • 130
  • "in a future version of the CLR that object size for LOH consideration could indeed be dynamic" - *because* of that, I would assume the runtime to give any dynamic info about it. – user492238 Jan 27 '11 at 11:08
  • @user492238 The fact that you know some things about LOH management, but none of this is bubbled up to the API is simply the product of the CLR designers not wanting users to rely on specific implementation details directly. This is good software design in practice as they are encapsulating a design aspect that is very much about optimization. If they allowed you to couple yourself to aspects of it, it would prevent them from completely changing it. – Tim Lloyd Jan 27 '11 at 11:16
  • @user492238 Down-voting isn't going to win you any respect. With respect, I am replying to your comments and questions. – Tim Lloyd Jan 27 '11 at 11:24
  • @chibacity: I agree. if it was perfect design, the user would not need to know anything about internals. In fact, designers themself recommend special handling for special cases (without giving specific details). GC.GetGeneration, GC.Collect are just some examples regarding memory management. The managed heap is art in some perspective. Since it (of course) cannot handle ALL situations, implementors *must* sometimes keep track of special cases - one of them being memory fragmentation. – user492238 Jan 27 '11 at 11:28
  • @user492238 But you do know things about the internals, they are just not giving you any guarantees about them by bubbling them up to the API. They do not want coupling in this area. – Tim Lloyd Jan 27 '11 at 11:32
  • @user492238 Down-voting users that are trying to answer your question is pretty poor in my opinion, an opinion that is generally shared on SO. If you are going to down-vote, please give a reason. If you don't like the fact the CLR designers do not want you to know the 85k limit via the API that's tough luck, it's not my fault! :) – Tim Lloyd Jan 27 '11 at 11:36
  • @chibacity: downvoting is a regular feature of SO. You do not ask for reasons of upvoting comments like "The OP has some misunderstandings of IDisposable before we even get to things like LOH though". Please dont take it personally. I just thing, the answer is rated too high. It doesn't meet the point (yet). – user492238 Jan 27 '11 at 11:40
  • @user492238 Thanks for an enlightening insight into SO culture. Your down-vote has certainly provided me with added motivation to improve my answer to your excellent question. – Tim Lloyd Jan 27 '11 at 12:05
3

As chibacity said, IDisposable is not related with LOH management. Here is a good article on LOH: Large Object Heap Uncovered.

That being said, there is not any public API to determine the LOH size, as far as I know. You can find a reference to the 85000 bytes limit in SSCLI "rotor" (source available here: Shared Source Common Language Infrastructure 2.0 Release Download):

in clr/src/vm/gc.h:

#define LARGE_OBJECT_SIZE   85000

Although this source is a CLR 2.0 equivalent source, not CLR 4, I don't think they have changed this, as it would certainly have deep implication on existing code.

So if you want to do something smart with this value, you probably can put it safely in a constant, or make it configurable, but it will certainly not change dynamically during the course of the running process.

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • @Simon There are no public guarantees with LOH algorithms - that's *why* there is no API to get at parameters such as maximum object size in the first place. It is quite feasible that in a future version of the CLR that object size for LOH consideration could indeed be dynamic. – Tim Lloyd Jan 27 '11 at 10:53
  • @chibacity - I don't think I said something different. It's also possible that LOH disappear. Who can predict the future? – Simon Mourier Jan 27 '11 at 10:59
  • *Because* there is no overall guarantee, the user should get a chance to *find out* the current value at runtime, right? – user492238 Jan 27 '11 at 10:59
  • 2
    @Simon I agree completely - things could certainly change between versions of the CLR. The LOH could disappear completely. The OP has some misunderstandings of `IDisposable` before we even get to things like LOH though. – Tim Lloyd Jan 27 '11 at 11:04
  • "IDisposable is not related with LOH management" this is not true. Even the article you linked recommends pooling for large objects. The most natural implementation for poolable objects would be: IDisposable. – user492238 Jan 27 '11 at 11:05
  • Thanks for the reference to rotor. But I cannot see the relation to the question? – user492238 Jan 27 '11 at 11:06
  • @chibacity: "The OP has some misunderstandings of IDisposable" ... ? which would it be? Please see my edit above. – user492238 Jan 27 '11 at 11:20
  • @user492238 The following example from your question makes no sense: "For "smaller" arrays on the other hand, IDisposal does not make sense from a memory consumption point of view" – Tim Lloyd Jan 27 '11 at 11:23
  • It does make sence: Objects laying on Gen0/Gen1/Gen2 do not need such special handling as LOH objects do, since those parts of the heap are compacted by the GC. – user492238 Jan 27 '11 at 11:32
  • @user492238 Again - If you wish to reply to other user's comments, please include their @username or they will not be notified. – Tim Lloyd Jan 27 '11 at 11:34
  • @user492238 `IDisposable` has nothing to do with the following: "t does make sence: Objects laying on Gen0/Gen1/Gen2 do not need such special handling as LOH objects do, since those parts of the heap are compacted by the GC" – Tim Lloyd Jan 27 '11 at 11:35
  • @chibacity: Again, the question has nothing really to do with IDisposable. IDisposable **can** be used to implement handling of large arrays. For pooling scenarios it simply would be helpful to get a hint from the runtime, to decide, if objects must be pooled or not - f.e. As you stated several times: there is no guarantee by now, which objects target the LOH. So we need to find out on another way. – user492238 Jan 27 '11 at 11:52