Массовое использование памяти spike commitWrite () с Realm - PullRequest
0 голосов
/ 05 ноября 2018

Мы видим резкий скачок в использовании памяти при вставке большого количества данных (точнее, при совершении транзакции). Конечно, мы хотели бы избежать этого давления памяти. Вот быстрый скриншот, а более подробно ниже

enter image description here

  • Используемая версия Realm swift: 3.11.0
  • iOS: 12
  • Количество данных для вставки: 200 мес., Более 270 тыс. Объектов

Плюс, у нас есть следующие требования:

  • Загружаем данные с удаленного SQL Server
  • Мы должны быть уверены, что все данные были правильно загружены, поскольку мы не хотим, чтобы в результате возникла ошибка в целостности нашей базы данных (пропущенные данные)

Итак, с этим мы решили следующие шаги:

  • Хранение всех загруженных данных во временных отдельных файлах (на диске)
  • Как только все загруженные данные завершены, мы заходим в определенную очередь операций
  • Открываем транзакцию
  • Открываем файл за файлом, сохраняем объекты, затем закрываем файл
  • Если в процессе нет ошибок, подтвердите транзакцию
  • И в этот момент мы видим всплеск памяти при совершении транзакции

Это переводится примерно так в терминах кода (упрощенно)

//We have a small helper, that is use also for other classes
static func getRealm() -> Realm {
        do {
            let realm = try Realm()
            return realm
        } catch let error as NSError {
                //Log + error
        }
}

// The code where the spike occurs
DispatchQueue.global(qos: .background).async {
    do {
        // opening transaction
        RealmHelper.getRealm().beginWrite()

        let filesURL = StorageHelper.retrieveFilesURL()
        for fileURL in filesURL {
            autoreleasepool { // to clear decoded data
                //Retrieving data + Decoding objects
                let objects = StorageHelper.retrieve(forURL: fileURL)
                realm.add(objects.persons, update: true)
                realm.add(objects.buildings, update: true)
                // and so on (15 differents objects types)
            }
        }

        RealmHelper.getRealm().commitWrite()
    } catch let error as NSError {
        RealmHelper.getRealm().cancelWrite()
    }
}

Пока он работает, вы думаете, этот подход является лучшим? Есть ли способ уменьшить всплеск памяти? Сначала мы думали, что, сохраняя объекты по частям и пакетируя сохранение, это позволит избежать такого поведения, но это не так. И, как я уже говорил ранее, мы не можем разделить на несколько транзакций (плюс, согласно документации, это не рекомендуется для большого количества данных).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...