Какой смысл того, чтобы использовать GC.AddMemoryPressure с неуправляемым ресурсом?

Мы используем репликацию и кластеризацию для управления нашими базами данных, а также для резервного копирования. Мы используем Serena для управления нашими сценариями SQL и реализацией конфигурации. Перед внесением изменений в конфигурацию мы выполняем резервное копирование как часть процесса управления изменениями. Эта резервная копия удовлетворяет нашему требованию отката.

Я думаю, что все зависит от масштаба. Вы говорите о корпоративных приложениях, которые нуждаются в резервном копировании и удаленном восстановлении? Небольшая рабочая группа, работающая с бухгалтерским приложением? Или где-то посередине?

14
задан phwd 22 August 2011 в 00:57
поделиться

2 ответа

Задача AddMemoryPressure - сообщить сборщику мусора, что для этого объекта выделен большой объем памяти. Если он неуправляемый, сборщик мусора не знает об этом; только управляемая часть. Поскольку управляемая часть относительно мала, сборщик мусора может пропускать ее для сборки мусора несколько раз, по существу тратя впустую память, которую, возможно, потребуется освободить.

Да, вам все равно придется вручную выделять и освобождать неуправляемую память. От этого никуда не деться. Вы просто используете AddMemoryPressure, чтобы убедиться, что сборщик мусора знает об этом.

Редактировать:

Ну, в первом случае, я мог бы это сделать, но это не имело бы большого значения, так как сборщик мусора не смог бы ничего сделать с моим типом, если я правильно понимаю: 1) Я бы объявил свою переменную, 8 управляемых байтов, 2 МБ неуправляемых байтов. Затем я бы использовал его, вызвал dispose, чтобы освободить неуправляемую память. Прямо сейчас это будет только 8 байтов. Теперь, на мой взгляд, вызов AddMemoryPressure и RemoveMemoryPressure в конце ничего не изменил бы. Что я ошибаюсь? Извините за то, что вас это раздражает. - Хорхе Бранко

Думаю, я вижу вашу проблему.

Да, если вы можете гарантировать, что всегда вызываете Dispose , то да, вам не нужно возиться с AddMemoryPressure и RemoveMemoryPressure. Эквивалентности нет, поскольку ссылка все еще существует, и тип никогда не будет собран.

Тем не менее, вы все равно хотите использовать AddMemoryPressure и RemoveMemoryPressure для полноты картины. Что, если, например, пользователь вашего класса забыл вызвать Dispose? В этом случае, если вы правильно реализовали шаблон Disposal, вы в конечном итоге вернете свои неуправляемые байты при финализации, то есть при сборе управляемого объекта. В этом случае вы хотите, чтобы давление памяти оставалось активным, чтобы объект с большей вероятностью был восстановлен.

9
ответ дан 1 December 2019 в 12:39
поделиться

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

Брэд Абрамс запись об этом довольно ясно:

Рассмотрим класс, который имеет очень маленький размер управляемого экземпляра, но содержит указатель на очень большой кусок неуправляемая память. Даже после того, как никто ссылается на управляемый экземпляр, мог остаться в живых какое-то время, потому что GC видит только управляемый экземпляр размер не думаю, что это «стоит it », чтобы освободить экземпляр. Итак, нам нужно «научить» GC об истинной стоимости этого экземпляра, чтобы он точно знать, когда пнуть сборник, чтобы освободить больше памяти в процесс.

12
ответ дан 1 December 2019 в 12:39
поделиться