Распределение памяти по структуре и классу - PullRequest
2 голосов
/ 09 февраля 2012

Я пишу приложение, которое будет создавать тысячи маленьких объектов и рекурсивно хранить их в массиве.Под «рекурсивным» я подразумеваю, что каждый экземпляр K будет иметь массив из K экземпляров, который будет иметь и массив из K экземпляров и т. Д., И этот массив + одно поле int являются единственными свойствами + некоторые методы.Я обнаружил, что использование памяти растет очень быстро даже для небольшого объема данных (около 1 МБ), а когда обрабатываемые данные составляют около 10 МБ, я получаю «OutOfMemoryException», не говоря уже о том, когда он больше (у меня 4 ГБ ОЗУ):).Так что вы предлагаете мне сделать?Я решил, что если бы я создал отдельный класс V для обработки этих объектов, чтобы экземпляры K имели только массив из K + одно целочисленное поле и делали K структурой, а не классом, это должно немного оптимизировать вещи -без сборки мусора и прочего ... Но это немного сложная задача, поэтому я бы предпочел спросить вас, хорошая ли это идея, прежде чем я начну полное переписывание:).

РЕДАКТИРОВАТЬ: Хорошо, некоторые абстрактныекод

public void Add(string word) {
    int i;
    string shorter;

    if (word.Length > 0) {
        i = //something, it's really irrelevant

        if (t[i] == null) {
            t[i] = new MyClass();
        }

        shorterWord = word.Substring(1); 

        //end of word
        if(shorterWord.Length == 0) {
            t[i].WordEnd = END;
        }

        //saving the word letter by letter
        t[i].Add(shorterWord);
        }
    }
}

Ответы [ 5 ]

4 голосов
/ 23 октября 2012

Для меня уже при более глубоком изучении этого у меня были следующие предположения (они могут быть неточными; я старею для программиста).Класс имеет дополнительное потребление памяти, потому что для его обращения требуется ссылка.Сохраните ссылку, и указатель размера Int32 необходим при 32-битной компиляции.Выделенный всегда в куче (не могу вспомнить, есть ли у C ++ другие возможности, я бы рискнул?)

Краткий ответ, найденный в этой статье, состоит в том, что Object имеет базовый размер 12 байтов + 4 возможно неиспользуемых байта в зависимости отваш класс (без сомнения, что-то связанное с заполнением).

http://www.codeproject.com/Articles/231120/Reducing-memory-footprint-and-object-instance-size

Другие проблемы, с которыми вы столкнетесь, связаны с массивами.Возможность будет управлять вашим собственным смещением в больший массив или массивы.Что, в свою очередь, приближается к чему-то, для чего лучше подойдет более эффективный язык.

Я не уверен, есть ли библиотеки, которые могут эффективно обеспечивать хранение небольших объектов.Вероятно, есть.

Я беру это на себя, использую Structs, управляю своим собственным смещением в большом массиве и использую надлежащие инструкции по упаковке, если он вам подходит (хотя я подозреваю, что это обходится во время выполнения нескольких дополнительных инструкций каждый разВы обращаетесь к неравномерно упакованным данным)

[StructLayout(LayoutKind.Sequential, Pack = 1)]
2 голосов
/ 28 марта 2012

Ваш стек взрывается.

Делайте это итеративно, а не рекурсивно.

Вы не взрываете системный стек, вы взрываете кодовый стек, вызовы функций 10K выдувают его из воды.

Вам нужна правильная рекурсия хвоста, которая простоитеративный взлом.

0 голосов
/ 09 февраля 2012

Просто перечислите свой рекурсивный алгоритм и очистите имена переменных.Если вы выполняете обход типа BFS и сохраняете все объекты в памяти, у вас кончится память.Например, в этом случае замените его на DFS.

Редактировать 1:

Вы можете ускорить алгоритм, оценив, сколько элементов вы сгенерируете, затем выделите егомного памяти сразу.По мере продвижения алгоритма пополняйте выделенную память.Это уменьшает фрагментацию и перераспределение и операции копирования на весь массив.Тем не менее, после того, как вы закончите работу с этими сгенерированными словами, вы должны удалить их из структуры данных, чтобы они могли быть скопированы, чтобы у вас не иссякло mem.

0 голосов
/ 09 февраля 2012

Вы можете использовать лучшую структуру данных каждая буква может быть байтом (a-0, b-1 ...). каждый фрагмент слова может быть проиндексирован, особенно подстроки - вам должно быть значительно меньше памяти (хотя это и снижает производительность)

0 голосов
/ 09 февраля 2012

Убедитесь, что в вашей системе достаточно памяти.Более 100 Мб + и т. Д. Это действительно зависит от вашей системы.Связанный список, рекурсивные объекты - это то, на что вы смотрите.Если вы продолжите повторение, оно достигнет предела памяти, и будет выдано исключение nomemoryexception.Убедитесь, что вы отслеживаете использование памяти в любой программе.Ничто не безгранично, особенно память.Если память ограничена, сохраните ее на диск.

Похоже, в вашем коде бесконечная рекурсия и выброшена нехватка памяти.Проверьте код.Там должно быть начало и конец в рекурсивном коде.В противном случае в какой-то момент он превысит 10 терабайт.

...