Частью процесса сбора мусора является фаза уплотнения. Во время этой фазы блоки выделенной памяти перемещаются, чтобы уменьшить утомление. Когда память выделяется, она не всегда выделяется сразу после того, как последний кусок выделенной памяти был остановлен. Таким образом, вы можете втиснуть немного больше, потому что сборщик мусора освобождает больше места, лучше используя доступное пространство.
Я пытаюсь запустить некоторые тесты, но моя машина не может их обработать. Попробуйте, он скажет GC
зафиксировать объекты в памяти, чтобы они не перемещались
byte[] b = new byte[10000];
GCHandle.Alloc(b, GCHandleType.Pinned);
list.Add(b);
Что касается вашего комментария, когда GC
меняет положение вещей, он ничего не стирает, он просто лучше использует все пространство памяти. Давайте попробуем снова и снова упростить это. Когда вы выделяете свой байтовый массив в первый раз, допустим, он вставляется в память с места 0 до 10000. В следующий раз, когда вы выделяете байтовый массив, он не гарантируется начать с 10001, он может начаться с 10500. Так что у вас есть 499 байт, которые не используются и не будут использоваться вашим приложением. Поэтому, когда GC
выполняет сжатие, он перемещает массив 10500 в 10001, чтобы иметь возможность использовать эти дополнительные 499 байтов. И опять же, это слишком упрощенно.