RealmSwift Список элементов утечки памяти проблема - PullRequest
0 голосов
/ 10 января 2020

Я обнаружил, что запись огромного количества данных в Realm за iOS вызывает нехватку памяти и cra sh После нескольких дней расследования я обнаружил, что Realm не выпускает неиспользуемые объекты в Список. Я запустил следующий пример:

class LeakTestList : Object{
    var items = List<LeakTestItem>()
}

class LeakTestItem : Object{
    @objc dynamic var data = 0
}


func leakTest()
{
    guard let realm = try? Realm() else
    {
        return
    }
    let leakTestList = LeakTestList()
    leakTestList.items.append(objectsIn: (0..<10000).map{LeakTestItem(value: ["data":$0])})
    try? realm.write {
        realm.add(leakTestList)
    }
}

После возврата leakTest() я получил следующий профиль памяти:

Realm memory leak test

LeakTestList уже ушел, но все предметы остаются в памяти. Это вызвано нехваткой памяти, когда я пытался написать много элементов списка, даже разделенных на несколько достаточно коротких списков. Это ошибка от Realm или я могу что-то сделать, чтобы решить проблему?

Ответы [ 2 ]

0 голосов
/ 13 января 2020

Ссылаясь на ответ @Jay, я могу удалить объем памяти объектов области из монитора памяти, но использование памяти остается неизменным до конца viewDidLoad(). Оказалось, что после еще нескольких копаний ключевой идеей, которую я пропустил, было завернуть все в autoreleasepool. Ссылаясь на эту статью: https://realm.io/docs/cookbook/swift/object-to-background/

func leakTest()
{
    autoreleasepool {
        guard let realm = try? Realm() else
        {
            return
        }

        let leakTestList = LeakTestList()

        try? realm.write {
            realm.add(leakTestList)
        }

        try? realm.write {
            leakTestList.items.append(objectsIn: (0..<10000).map{LeakTestItem(value: ["data":$0])})
        }
    }
}
0 голосов
/ 11 января 2020

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

Наш проект должен был прочитать и обрабатывать файлы размером более 50 Гб, и мы обнаружили, что запись около 1000 объектов за раз, казалось, является балансом между скоростью, размером файла и памятью. Ваш пробег может отличаться.

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

Это пишет Всего 10 элементов меньшими порциями, что, как упоминалось в моем комментарии, уменьшает общий размер файла. для вашего примера внешнее значение l oop будет равно 40, а внутреннее значение будет равно 1000.

let leakTestList = LeakTestList()

try? realm.write {
    realm.add(leakTestList)
}

var index = 0
for _ in 0..<2 {
    var myItems = [LeakTestItem]()
    for _ in 0..<5 {
        let item = LeakTestItem( value: ["data": index] )
        myItems.append(item)
        index += 1
    }

    try? realm.write {
        leakTestList.items.append(objectsIn: myItems)
    }
}
...