2016-12-23 2 views
0

Я собираю строковые данные в структуре. В конце я пишу эту строку в файл. Результаты - 4 файла каждый 80 МБ. Но внутренне он занимал около 16 ГБ (!) Оперативной памяти, заставляя ОС обмениваться. (Я использую Swift 3.0)Огромное потребление памяти с помощью строк

struct ActionCMD { // struct! 
    var cmd = String() 

... 

    mutating func lines(_ text: String, toTheTop: Bool = false) { 
     if toTheTop { cmd = text + cmd } 
     else  { cmd += text } 
    } 
... 
} 

Любая идея, почему это происходит и как этого избежать?

+1

Похоже, что у вас где-то есть утечка памяти. Вы запускали инструменты и проверяли, что использует всю память? –

+0

Нет, я не знаю инструмент. Я ищу его (и как использовать) и попытаюсь изучить эту проблему. –

+0

Конечно, все в порядке, но вы можете переписать свой «ActionCMD» как «класс», если это не повредит вашей архитектуре. – Leo

ответ

1

Возможно, это связано с методом (-ами), обозначенным как mutating. A mutating метод в Swift применит свои «изменения к новой копии, в данном случае, экземпляра ActionCMD. В зависимости от остальной части кода вы можете хранить все эти экземпляры.

+0

Это интересно. Я изменяю строку внутри структуры, поэтому она мутирует. Есть ли другой способ сделать это без этого эффекта, но (!) Сохранить его Swift-like? Переключение с структуры на класс делает это еще хуже? Может быть, нет, потому что я не создаю больше объектов, а не меняю себя? –

+0

Структуры в Swift - это тип значения, который, похоже, не очень хорошо поддерживает ваш прецедент. Вы можете сделать 'ActionCMD' класс с переменной экземпляра' var cmdComponents: [String] = [] '. Когда вы заполнили этот массив всеми строками в правильном порядке, вы можете сделать из него одну строку с помощью 'cmdComponents.reduce (" ", comb: +)'. –

+0

Спасибо. Я сделал класс и использовал массив, и, похоже, он уменьшает потребление памяти до половины. Еще 8,5 ГБ !? Но я не вижу дальнейших оптимизаций. –

-1

В C# и Java вы должны использовать строковый конструктор, потому что новая строка создается каждый раз, когда вы добавляете что-то, если вы этого не делаете. Строковый блок выделяет память только один раз.

Это: http://cocoadocs.org/docsets/StringBuilder/ Кажется, это порт от Java до Swift, не проверял его, но вы можете попробовать.

Этот: https://gist.github.com/kristopherjohnson/1fc55e811d944a430289 очень плохой (первый результат на Google грустно). Это не строковое построение, а просто оболочка вокруг обычных методов.

0

Прежде всего, вам сложно сказать, что не так в вашем приложении, не зная, как вы распределяете и освобождаете эти экземпляры. Проблемы, которые вы видите, могут быть связаны с сохранением циклов или с тем, как вы собираете данные String. String - тип значения, и из-за этого каждый раз, когда вы его изменяете, новая копия будет создана из-за функции копирования на запись. Тем не менее, лучший совет, который я могу вам дать, - это проверить это довольно good article на несколько советов по улучшению управления памятью с помощью ObjC и Swift. Надеюсь это поможет.