Во время разговора с коллегой о конкретной группе приложений, использующих почти 1,5 ГБ памяти при запуске ... он указал мне на очень хорошую ссылку на .NET отладку продукции
То, что меня озадачило, это ...
Например, если вы выделите 1 МБ
память на один блок, большой
Размер кучи объекта увеличивается до 1 МБ.
Когда вы освобождаете этот объект, большой
куча объектов не разрушает
виртуальная память, поэтому куча остается на 1
МБ в размере. Если вы выделите другой
500-килобайтный блок позже, новый блок
выделяется в пределах 1 МБ блока
память, принадлежащая большому объекту
куча. В течение срока службы процесса
куча больших объектов всегда растет
все большие выделения блоков
в настоящее время упоминается, но никогда
сжимается, когда объекты выпущены,
даже если происходит сборка мусора.
Рисунок 2.4 на следующей странице показывает
пример кучи большого объекта.
Теперь, допустим, у нас есть вымышленное приложение, которое создает поток больших объектов (> 85 КБ), поэтому объем кучи больших объектов увеличивается, скажем, до 200 Мег. Теперь допустим, что у нас запущено 10 таких экземпляров приложения, так что выделено 2000 мегабайт. Теперь эта память никогда не возвращается ОС, пока процесс не завершится ... (это я понял)
Есть ли пробелы в моем понимании? Как нам вернуть неиспользованную память в различных LOHeaps; мы не создаем идеальный шторм OutOfMemoryExceptions?
Обновление: Из ответа Марка я хотел уточнить, что на объекты LOH не ссылаются - большие объекты используют use-n-throw - однако куча не уменьшается, хотя куча относительно пустой пост начального всплеска.
Обновление № 2: Просто включил фрагмент кода (преувеличено, но я думаю, что это понятно). Я вижу исключение OutOfMemoryException примерно в то время, когда виртуальная память достигает отметки 1,5G на моей машине (1,7 G на другом) .. Из в блоге Эрика Л. , «память процесса может быть визуализирована как массивный файл на диске ...» - этот результат, таким образом, является неожиданным. У машин в этом случае было ГБ свободного места на жестком диске. Налагает ли файл ОС PageFile.sys (или связанные с ним настройки) какие-либо ограничения?
static float _megaBytes;
static readonly int BYTES_IN_MB = 1024*1024;
static void BigBite()
{
try
{
var list = new List<byte[]>();
int i = 1;
for (int x = 0; x < 1500; x++)
{
var memory = new byte[BYTES_IN_MB + i];
_megaBytes += memory.Length / BYTES_IN_MB;
list.Add(memory);
Console.WriteLine("Allocation #{0} : {1}MB now", i++, _megaBytes);
}
}
catch (Exception e)
{ Console.WriteLine("Boom! {0}", e); // I put a breakpoint here to check the console
throw;
}
}
static void Main(string[] args)
{
BigBite();
Console.WriteLine("Check VM now!"); Console.ReadLine();
_megaBytes = 0;
ThreadPool.QueueUserWorkItem(delegate { BigBite(); });
ThreadPool.QueueUserWorkItem(delegate { BigBite(); });
Console.ReadLine(); // will blow before it reaches here
}