Тайна Сборщика "мусора".NET

Вы можете вызвать кеш-хранилище и выполнить сброс, используя приведенные ниже:

handleLogout = () => {
        const { client } = this.props;

        client.cache.reset().then(() => {
            history.push('/login')
        })

28
задан Bart 18 January 2013 в 16:34
поделиться

3 ответа

Частью процесса сбора мусора является фаза уплотнения. Во время этой фазы блоки выделенной памяти перемещаются, чтобы уменьшить утомление. Когда память выделяется, она не всегда выделяется сразу после того, как последний кусок выделенной памяти был остановлен. Таким образом, вы можете втиснуть немного больше, потому что сборщик мусора освобождает больше места, лучше используя доступное пространство.

Я пытаюсь запустить некоторые тесты, но моя машина не может их обработать. Попробуйте, он скажет GC зафиксировать объекты в памяти, чтобы они не перемещались

byte[] b = new byte[10000];
GCHandle.Alloc(b, GCHandleType.Pinned);
list.Add(b);

Что касается вашего комментария, когда GC перемещает вещи, он ничего не стирает, просто лучше использует все пространство памяти. Давайте попробуем снова и снова упростить это. Когда вы выделяете свой байтовый массив в первый раз, допустим, он вставляется в память с места 0 до 10000. В следующий раз, когда вы выделяете байтовый массив, он не гарантируется начать с 10001, он может начаться с 10500. Так что теперь у вас есть 499 байт, которые не используются и не будут использоваться вашим приложением. Поэтому, когда GC выполняет сжатие, он перемещает массив 10500 на 10001, чтобы иметь возможность использовать эти дополнительные 499 байтов. И опять же, это слишком упрощенно.

11
ответ дан Bob 28 November 2019 в 03:54
поделиться

CLR иногда помещает массивы в LOH. Если вы когда-нибудь посмотрите на дамп памяти через WinDbg, вы увидите, что есть массивы, размер которых меньше 85 000 байт. Это недокументированное поведение - но так оно и есть.

Вы получаете OutOfMemoryErrors, потому что вы фрагментируете кучу LOH, а куча LOH никогда не сжимается.

Что касается вашего вопроса:

2) Что, черт возьми, может собрать GC, когда нет «потерянных» ссылок (я даже предварительно настроил емкость Списка)?

Существуют перезаписанные ссылки на new byte[10000], которые вы передаете, чтобы добавить в список. Локальная переменная компилируется и присваивается new byte[10000]. Для каждой итерации в цикле вы создаете новый byte [] с предопределенным размером 10000, и он назначается локальной переменной. Любое предыдущее значение для переменной будет перезаписано, и эта память будет пригодна для сбора при следующем запуске GC для генерации, в которой живет переменная (в данном случае, возможно, LOH).

2
ответ дан Dave Black 28 November 2019 в 03:54
поделиться

В зависимости от используемой среды CLR могут возникнуть проблемы с кучей больших объектов.

Прочтите эту статью, что объясняет проблемы с распределением больших блоков (и список из 200000 элементов, безусловно, является большим блоком, другой может быть, а может и не быть, некоторые массивы, похоже, помещаются в LOH, когда они достигают 8k, другие после 85k).

http://www.simple-talk.com/dotnet/. net-framework / the-dangers-of-the-large-object-heap /

5
ответ дан 28 November 2019 в 03:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: