Будет ли мой объект помещен в кучу больших объектов?
Когда 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
?
2 ответа
Каждый из байтовых массивов, которые вы выделяете, обрабатывается отдельно от включающего класса. Таким образом, OneBigObject - это фактически два разных объекта CLR. Одним из них является экземпляр OneBigObject, который очень мал и содержит только поле ссылки. Другой фактический байтовый массив из 100000 экземпляров. Тот же принцип применим и к другим классам.
Классы и структуры не разделены. В этом нет необходимости, поскольку трудно представить, чтобы кто-то создавал тип, в котором было бы достаточно фактических полей, чтобы его объем хранилища составлял 85 КБ. Крупно выглядящие объекты, такие как ваш пример, на самом деле состоят из ссылок и массивов ссылок и поэтому не очень большие.
Размер TwoSmallObjects
(игнорируя издержки, которые есть у каждого объекта) всего 8 байтов (16 в 64-битном процессе). Точно так же размер MixedSizeObjects
всего 24 байта (48 на 64-битной).
Таким образом, чтобы ответить на ваш вопрос, ни один из этих объектов не попадает в LOH. Массивы, на которые они ссылаются, могут зависеть от размера каждого отдельного массива.
Я не могу представить, как будет работать система, которая будет работать так, как вы ожидаете. Особенно с учетом того, что конструктор запускается после выделения объекта. Как распределитель узнает, что вы собираетесь назначить его полям, прежде чем на самом деле это сделать? Должен ли он переместить объект в LOH, если вы это сделаете? Зачем ему делать всю эту работу, если это ничего не помогает.
Еще одна вещь, которая может помочь: если у вас есть тип ссылочного типа (а массив - один), поле не содержит объект. Он содержит только ссылку.