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

Когда 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, если вы это сделаете? Зачем ему делать всю эту работу, если это ничего не помогает.

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

Другие вопросы по тегам