Как уменьшить выделение памяти для типов данных, срок жизни которых не определенC#

Место общения программистов C#
Ответить
Anonymous
 Как уменьшить выделение памяти для типов данных, срок жизни которых не определен

Сообщение Anonymous »

У меня есть тип данных, время жизни которого не определено. Поэтому это класс. Однако он создается очень часто, что заставляет его постоянно выделять память. Он также имеет довольно большой вес, что делает его проблематичным.
Что можно сделать, чтобы уменьшить количество выделений, необходимых для этого типа данных, оптимизировать их выделение и освобождение, а также уменьшить объем GC давление? (Создать структуру не получится, так как потребуется постоянное копирование данных, с невозможностью всегда освободить данные из внутреннего массива через try-finally).

Код: Выделить всё

[Serializable]
public class DamageData
{
[Serializable]
public class DamageDataInternal
{
public float[] values;
public float totalDamage;
public int cachedHashCode;
public bool isHashCodeDirty;
}

private DamageDataInternal _internalData;

public static readonly DamageType[] DamageTypes;

public int Hash => GetHashCode();
public bool IsInit => _internalData != null;

static DamageData()
{
DamageTypes = (DamageType[])Enum.GetValues(typeof(DamageType));
}

~DamageData()
{
DamageDataInternalPool.Shared.Release(_internalData);
_internalData = null;
}

public DamageData()
{
_internalData = DamageDataInternalPool.Shared.Get();
_internalData.totalDamage = 0f;
_internalData.isHashCodeDirty = true;
_internalData.cachedHashCode = 0;
}
}

Код: Выделить всё

using UnityEngine.Pool;
public class DamageDataInternalPool
{
private readonly ObjectPool _pool;

public static DamageDataInternalPool Shared { get; } = new();

public DamageDataInternalPool()
{
_pool = new ObjectPool(
createFunc: () => new DamageData.DamageDataInternal(),
actionOnGet: obj =>
{
obj.totalDamage = default;
obj.cachedHashCode = default;
obj.isHashCodeDirty = default;
obj.values = ArrayPool.Shared.Rent(DamageData.DamageTypes.Length);
for (var i = 0; i < DamageData.DamageTypes.Length; i++)
{
obj.values[i] = 0f;
}
},
actionOnRelease: obj =>
{
ArrayPool.Shared.Return(obj.values);
},
actionOnDestroy: null,
defaultCapacity: 10,
maxSize: 10000
);
}

public DamageData.DamageDataInternal Get()
{
return _pool.Get();
}

public void Release(DamageData.DamageDataInternal obj)
{
_pool.Release(obj);
}
}
Я попытался инкапсулировать его внутренние данные в отдельный класс, экземпляры которого я получаю через пул объектов, чтобы основной класс весил всего SIZE_OF_LINK + SOME_META_DATA_SIZE. Однако, похоже, это совсем не изменило ситуацию, и ассигнований по-прежнему много.

Подробнее здесь: https://stackoverflow.com/questions/793 ... -undefined
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»