以编程方式确定大对象堆的限制
由于建议对大型对象使用 IDisposal 模式,我想知道为什么似乎没有可靠的方法来确定对象被视为“大”的限制?
在内部存在这样的区别:在 LOH 上分配的对象的下限。每当它被公开传达为 85k 时,就会同时阻止人们依赖该数字。
特别是对于处理大量“较大”数组的应用程序,必须需要该限制才能实现正确的内存管理并防止 LOH 碎片。另一方面,对于“较小”的数组,从内存消耗的角度来看,IDisposal 没有意义。在这里,压缩 GC 做得更好。
为什么没有这样的东西
GC.GetLOHLimit()
甚至更好:
bool GC.ArrayTargetForManualDisposal(Type type, int length);
编辑:我知道,IDisposable 模式只是正确处理特殊对象(例如“大”或非托管对象)的建议。我的问题并不是假设运行时会对这些对象进行任何特殊处理。我宁愿要求该模式的实现者(也可能是其他人)提供运行时支持,以了解对象何时应该遵循特殊的内存管理。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
IDisposable
与托管内存管理无关。对象的处置是一种用户约定\模式,它不被运行时内部使用,并且对内存管理没有影响。运行时不知道IDisposable
。IDisposable
的唯一特殊处理\识别是与using
关键字一起使用时,但这是由编译器(至少是 C# 编译器)识别的,而不是运行时识别的。至于 LOH,LOH 算法没有公共保证 - 这就是为什么首先没有 API 来获取最大对象大小等参数。在 CLR 的未来版本中,考虑 LOH 的对象大小确实可以是动态的,这是完全可行的。 CLR 设计者不希望用户将自己与内存管理的内部细节耦合起来,因为这将使他们更难或不可能在不破坏大量现有程序的情况下对其进行更改。
如果您关心 CLR 内存管理,我首先建议您了解 IDisposable 不参与其中的事实。
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 ofIDisposable
. The only special treatment\recognition ofIDisposable
is when used with theusing
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.正如chibacity所说,IDisposable与LOH管理无关。这是一篇关于 LOH 的好文章:大对象堆揭秘。
话虽这么说,据我所知,没有任何公共 API 可以确定 LOH 大小。您可以在 SSCLI“rotor” 中找到对 85000 字节限制的引用(来源可在此处获取:< a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyId=8C09FD61-3F26-4555-AE17-3121B4F51D4D&displaylang=en" rel="nofollow">共享源公共语言基础结构 2.0发布下载):
在 clr/src/vm/gc.h 中:
虽然这个源是 CLR 2.0 等效源,而不是 CLR 4,但我认为他们没有改变这一点,因为它肯定会有深刻的含义在现有代码上。
因此,如果你想用这个值做一些聪明的事情,你可能可以将它安全地放在一个常量中,或者使其可配置,但它肯定不会在运行过程中动态改变。
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:
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.