У меня есть другой активный вопрос ЗДЕСЬ относительно некоторых безнадежных проблем памяти, которые возможно включают Фрагментацию LOH среди возможно других неизвестных.
Каков мой вопрос теперь, каков принятый способ сделать вещи? Если мое приложение должно быть сделано в Визуальном C# и должно иметь дело с большими массивами в размере интервала [4000000], как я не могу быть обречен отказом сборщика "мусора" иметь дело с LOH?
Казалось бы, что я вынужден сделать любые большие массивы глобальными, и никогда не использовать слово, "новое" вокруг ни одного из них. Так, меня оставляют с неизящными глобальными массивами с "maxindex" переменными вместо аккуратно размерных массивов, которые розданы функциями.
Мне всегда говорили, что это было плохой практикой. Что альтернатива там?
Есть ли некоторая функция в размере System.GC.CollectLOH("Seriously")
? Есть ли возможно некоторый способ произвести сборку "мусора" на стороне к чему-то другому, чем Система. GC?
Так или иначе, каковы общепринятые правила для контакта с большим (> 85 КБ) переменные?
Во-первых, сборщик мусора действительно собирает LOH, поэтому не пугайтесь его присутствия. LOH собирается, когда собирается поколение 2.
Разница в том, что LOH не уплотняется, а это означает, что если у вас есть объект с длительным сроком службы, вы фактически разделите LOH на две части - область до и область после этого объекта. . Если такое поведение будет продолжаться, вы можете столкнуться с ситуацией, когда пространство между долгоживущими объектами недостаточно велико для последующих назначений, и .NET должен выделять все больше и больше памяти для размещения ваших больших объектов, то есть LOH становится фрагментированным.
Теперь, сказав это, LOH может уменьшаться в размере, если область на его конце полностью свободна от живых объектов, поэтому единственная проблема заключается в том, если вы оставляете объекты там на долгое время (например, продолжительность приложения ).
Начиная с .NET 4.5.1, LOH можно было сжать, см. Свойство GCSettings.LargeObjectHeapCompactionMode .
Стратегии предотвращения фрагментации LOH:
Изменить: порог LOH для двойных массивов составляет 8k.
Первое, что приходит в голову, - это разбить массив на более мелкие. , поэтому они не достигают объема памяти, необходимой для того, чтобы сборщик мусора поместил в него LOH. Вы можете разделить массивы на более мелкие, скажем, 10 000, и построить объект, который будет знать, в какой массив искать, на основе переданного вами индексатора.
Я не видел кода, но хотел бы также спросить, зачем вам такой большой массив. Я бы потенциально посмотрел на рефакторинг кода, чтобы всю эту информацию не нужно было сразу хранить в памяти.
Вы ошиблись. Вам НЕ нужно иметь размер массива 4000000, и вам определенно не нужно вызывать сборщик мусора.
Это позволяет вам получить доступ практически ко всем вашим элементам только с ОДНОЙ переадресацией. И, поскольку отдельные массивы меньше, фрагментация не является проблемой ...
... если это так ... то ПОВТОРИТЕ страницы. Не выбрасывайте их при утилизации, поместите их в статический «PageList» и сначала вытащите их оттуда. Все это можно сделать прозрачно внутри вашего класса.
Действительно хорошо то, что этот список довольно динамичен в использовании памяти. Вы можете изменить размер массива держателей (перенаправителя). Даже если это не так, это всего лишь около 512 КБ данных на страницу.
Массивы второго уровня в основном имеют 64 КБ на байт, что составляет 8 байтов для класса (512 КБ на страницу, 256 КБ для 32-битных) или 64 КБ на байт структуры.
Технически:
Превратите int [] в int [] []
Решите, что лучше: 32 или 64 бит;) Оба Есть преимущества и недостатки.
Работа с ОДНИМ большим массивом, подобным этому, неуместна на любом языке - если хотите, то ... в основном .... выделяйте при запуске программы и никогда не создавайте заново. Единственное решение.