Вы можете вызвать кеш-хранилище и выполнить сброс, используя приведенные ниже:
handleLogout = () => {
const { client } = this.props;
client.cache.reset().then(() => {
history.push('/login')
})
Частью процесса сбора мусора является фаза уплотнения. Во время этой фазы блоки выделенной памяти перемещаются, чтобы уменьшить утомление. Когда память выделяется, она не всегда выделяется сразу после того, как последний кусок выделенной памяти был остановлен. Таким образом, вы можете втиснуть немного больше, потому что сборщик мусора освобождает больше места, лучше используя доступное пространство.
Я пытаюсь запустить некоторые тесты, но моя машина не может их обработать. Попробуйте, он скажет GC
зафиксировать объекты в памяти, чтобы они не перемещались
byte[] b = new byte[10000];
GCHandle.Alloc(b, GCHandleType.Pinned);
list.Add(b);
Что касается вашего комментария, когда GC
перемещает вещи, он ничего не стирает, просто лучше использует все пространство памяти. Давайте попробуем снова и снова упростить это. Когда вы выделяете свой байтовый массив в первый раз, допустим, он вставляется в память с места 0 до 10000. В следующий раз, когда вы выделяете байтовый массив, он не гарантируется начать с 10001, он может начаться с 10500. Так что теперь у вас есть 499 байт, которые не используются и не будут использоваться вашим приложением. Поэтому, когда GC
выполняет сжатие, он перемещает массив 10500 на 10001, чтобы иметь возможность использовать эти дополнительные 499 байтов. И опять же, это слишком упрощенно.
CLR иногда помещает массивы в LOH. Если вы когда-нибудь посмотрите на дамп памяти через WinDbg, вы увидите, что есть массивы, размер которых меньше 85 000 байт. Это недокументированное поведение - но так оно и есть.
Вы получаете OutOfMemoryErrors, потому что вы фрагментируете кучу LOH, а куча LOH никогда не сжимается.
Что касается вашего вопроса:
2) Что, черт возьми, может собрать GC, когда нет «потерянных» ссылок (я даже предварительно настроил емкость Списка)?
Существуют перезаписанные ссылки на new byte[10000]
, которые вы передаете, чтобы добавить в список. Локальная переменная компилируется и присваивается new byte[10000]
. Для каждой итерации в цикле вы создаете новый byte [] с предопределенным размером 10000, и он назначается локальной переменной. Любое предыдущее значение для переменной будет перезаписано, и эта память будет пригодна для сбора при следующем запуске GC для генерации, в которой живет переменная (в данном случае, возможно, LOH).
В зависимости от используемой среды CLR могут возникнуть проблемы с кучей больших объектов.
Прочтите эту статью, что объясняет проблемы с распределением больших блоков (и список из 200000 элементов, безусловно, является большим блоком, другой может быть, а может и не быть, некоторые массивы, похоже, помещаются в LOH, когда они достигают 8k, другие после 85k).
http://www.simple-talk.com/dotnet/. net-framework / the-dangers-of-the-large-object-heap /