Будет ли мой объект помещен в большую кучу объектов?


Когда среда 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 2

2 ответа:

Каждый из выделяемых массивов байтов обрабатывается отдельно от заключающего класса. Таким образом, OneBigObject-это фактически два разных объекта CLR. Одним из них является экземпляр OneBigObject, который очень мал и содержит только ссылочное поле. Другой-это фактический массив байтов из 100 000 экземпляров. Тот же принцип применим и к другим классам.

Классы и структуры не разделяются. В этом нет необходимости, потому что трудно представить себе кого-либо, создающего тип, который имеет достаточно фактических полей, чтобы сделать его 85k в размере хранилища. Большие на вид объекты, как в вашем примере, на самом деле состоят из ссылок и массивов ссылок и поэтому не очень большие вообще.

Размер TwoSmallObjects (игнорируя накладные расходы каждого объекта) составляет всего 8 байт (16 в 64-битном процессе). Аналогично, размер MixedSizeObjects составляет всего 24 байта (48 на 64-битном).

Итак, чтобы ответить на ваш вопрос, ни один из этих объектов не входит в LOH. Массивы, на которые они ссылаются, могут, в зависимости от размера каждого отдельного массива. Я не могу себе представить, как будет работать система, которая будет работать так, как вы ожидаете. Особенно учитывая, что конструктор запускается после выделения объекта. Как будет ли распределитель знать, что вы собираетесь назначить его полям, прежде чем вы это сделаете? Должен ли он переместить объект в лох, если вы это сделаете? Зачем ей делать всю эту работу, если она ничему не помогает.

Еще одна вещь, которая может помочь: если у вас есть тип ссылочного типа (и массив является одним), поле не содержит объект. Он содержит только ссылку .