Фрагментация кучи больших объектов, проблемы с массивами

Я пишу приложение для анализа на C #, которое имеет дело с большим объемом памяти. Я использую ANTS Memory Profiler 7.4 для оптимизации управления памятью. При этом я понял, что все мои массивы double [,], которые я использую (и они мне нужны), размещены на LOH, хотя самый большой из этих массивов составляет около 24 000 байт. Насколько я знаю, объекты не должны быть помещены туда раньше 85000 байт. Проблема в том, что, поскольку у меня есть около нескольких тысяч экземпляров этих массивов double [,], у меня много фрагментации памяти (около 25% моего общего использования памяти - это свободная память, которую я не могу использовать). некоторые из этих массивов, хранящихся в LOH, имеют размер всего 1,036 байта. Проблема в том, что иногда мне приходится выполнять более обширный анализ, а затем я получаю исключение нехватки памяти из-за значительной потери памяти из-за фрагментации LOH.

Кто-нибудь знает, почему это происходит, хотя по определению это не должен быть большой объект?

Снимок памяти моего приложения с использованием профилировщика памяти ANTS

это также влияет на небольшие двойные массивы (всего 70 элементов в массиве)


person Oliver Bernhardt    schedule 03.08.2012    source источник
comment
взгляните на этот ответ!   -  person mtijn    schedule 03.08.2012
comment
Я видел это, но сначала я не работаю со строками здесь, а также ответ о двойных массивах не подходит для моих задач, поскольку многие из моих двойных [,] массивов на LOH даже не имеют 6 элементов. так что это действительно оставляет меня в неведении. но спасибо за ответ. Я уже видел этот пост раньше, но это не совсем решило мою проблему.   -  person Oliver Bernhardt    schedule 03.08.2012


Ответы (1)


Пороговый размер для размещения массивов дублей на LOH намного ниже, чем для других типов. Причина этого в том, что элементы в LOH всегда выровнены по 64-битному разряду, а для удвоений значительно выигрывают от выравнивания по 64-битному разряду.

Обратите внимание, что это влияет только на программы, работающие в 32-битном формате. В 64-битных программах есть объекты, которые всегда выровнены по 64-битной границе, поэтому эвристика LOH не используется для 64-битных программ.

Размер порога - 1000 двойников.

См. Также https://connect.microsoft.com/VisualStudio/feedback/details/266330/

person Matthew Watson    schedule 03.08.2012
comment
как я уже сказал, это также влияет на массивы double [,] размером всего 6 записей. таким образом, массив, который находится на LOH, является массивом double [2,3], но я все еще заканчивается на LOH (со всеми другими массивами double [,], которые тоже больше). Но большинство моих массивов (около 90%) не превышают порог 1000 удвоений. хорошо, те, которые я показываю на скриншоте, превышают этот предел, но большинство - нет. что насчет них? почему они там оказываются? - person Oliver Bernhardt; 03.08.2012
comment
Происходит ли это даже в простой программе, которая выделяет только один массив? Интересно, не вызывает ли что-нибудь странное такое поведение? - person Matthew Watson; 03.08.2012
comment
Да ... Похоже, что массивы типа double [,] (многомерные) всегда помещаются на LOH независимо от их размера. Кто-нибудь знает, как этого избежать? потому что я их часто использую и не хотел бы полностью переделывать весь проект. - person Oliver Bernhardt; 06.08.2012
comment
Многомерные двойные массивы следуют тому же правилу в .NET Framework 4.6. Console.WriteLine(GC.GetGeneration(new double[31,31])); выходы 0 и Console.WriteLine(GC.GetGeneration(new double[32,32])); выходы 2. - person Antosha; 17.03.2017