我的对象会被放置在大对象堆中吗?
当 CLR 在大对象堆上放置一个对象时,这是一个“全有或全无”的交易吗?类/结构成员是否“拆分”并放置在不同的堆中?
class OneBigObject
{
byte[] bigObject;
public OneBigObject()
{
bigObject = new byte[100000];
}
}
class TwoSmallObjects
{
byte[] smallObject1;
byte[] smallObject2;
public TwoSmallObjects()
{
smallObject1 = new byte[50000];
smallObject2 = new byte[50000];
}
}
class MixedSizeObjects
{
byte[] smallObject1;
byte[] smallObject2;
byte[] bigObject;
public MixedSizeObjects()
{
smallObject1 = new byte[50000];
smallObject2 = new byte[50000];
bigObject = new byte[100000];
}
}
OneBigObject oneBigObject = new OneBigObject();
TwoSmallObjects twoObjects = new TwoSmallObjects();
MixedSizeObjects mixedSizeObjects = new MixedSizeObjects();
由于 TwoSmallObjects
的总大小超过 85,000 字节,因此是否将其放置在大对象堆上?即使两位成员各自都低于门槛? MixedSizeObjects
怎么样?
When the CLR places an object on the Large Object Heap, is it an "all or nothing" deal? Are class/struct members "split up" and placed in different heaps?
class OneBigObject
{
byte[] bigObject;
public OneBigObject()
{
bigObject = new byte[100000];
}
}
class TwoSmallObjects
{
byte[] smallObject1;
byte[] smallObject2;
public TwoSmallObjects()
{
smallObject1 = new byte[50000];
smallObject2 = new byte[50000];
}
}
class MixedSizeObjects
{
byte[] smallObject1;
byte[] smallObject2;
byte[] bigObject;
public MixedSizeObjects()
{
smallObject1 = new byte[50000];
smallObject2 = new byte[50000];
bigObject = new byte[100000];
}
}
OneBigObject oneBigObject = new OneBigObject();
TwoSmallObjects twoObjects = new TwoSmallObjects();
MixedSizeObjects mixedSizeObjects = new MixedSizeObjects();
Is TwoSmallObjects
placed on the Large Object Heap since its total size is over 85,000 bytes? Even though both members are individually under the threshold? What about MixedSizeObjects
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您分配的每个字节数组都与封闭类分开处理。所以OneBigObject实际上是两个不同的CLR对象。一种是 OneBigObject 实例,它非常小,仅包含一个引用字段。另一个是 100,000 个实例的实际字节数组。同样的原则也适用于其他类。
类和结构没有分开。没有必要,因为很难想象有人会创建一个具有足够实际字段的类型,使其存储大小达到 85k。像您的示例一样,看起来很大的对象实际上由引用和引用数组组成,因此根本不是很大。
Each of the byte arrays that you are allocating are treated separately from the enclosing class. So the OneBigObject is actually two different CLR objects. One is the OneBigObject instance that is very small and contains just a reference field. The other is the actual byte array of 100,000 instances. The same principle applies to the other classes as well.
Classes and structs are not split up. There is no need because it is hard to imagine anyone creating a type that has enough actual fields to make it 85k in storage size. Large looking objects, like your example, actually consist of references and arrays of references and so are not very big at all.
TwoSmallObjects
的大小(忽略每个对象的开销)仅为 8 个字节(64 位进程中为 16 个字节)。同样,MixedSizeObjects 的大小仅为 24 个字节(64 位为 48 个字节)。因此,回答你的问题,这些对象都不会进入 LOH。它们引用的数组可能取决于每个数组的大小。
我无法想象一个系统会如何按照您期望的方式工作。特别是考虑到构造函数在分配对象后运行。在您实际执行此操作之前,分配器如何知道您要为其字段分配什么?如果您这样做,是否应该将对象移动到 LOH?如果它没有任何帮助,为什么要完成所有这些工作。
另一件可能有帮助的事情是:如果您有一个引用类型(并且数组就是一个),则该字段不包含该对象。它仅包含参考。
The size of
TwoSmallObjects
(ignoring the overhead each object has) is just 8 bytes (16 in 64-bit process). Similarly, the size ofMixedSizeObjects
is just 24 bytes (48 on 64-bit).So, to answer your question, neither of those objects goes onto the LOH. The arrays they reference might, depending on the size of each individual array.
I can't imagine how would a system that would work the way you expect work. Especially considering that constructor runs after allocating the object. How would the allocator know what are you going to assign to its fields before you actually do that? Should it move the object to LOH if you do that? Why would it do all that work, if it doesn't help anything.
Another thing that might help: if you have a type of a reference type (and an array is one), the field doesn't contain the object. It contains just the reference.