#android #performance #kotlin #insert #realm
#Android #Производительность #kotlin #вставить #realm
Вопрос:
Я довольно новичок в Android и Kotlin.
У меня есть приложение, которое выполняет некоторые вычисления. Я пытаюсь провести некоторое тестирование производительности. Для этого я хочу создать 10000 объектов:
Thread().run() {
try {
val realm = Realm.getDefaultInstance()
// Test endedSessions
val sessions = realm.where<Session>().findAll()
if (sessions.size < 10) {
val numberOfSessions = 10000
realm.beginTransaction()
for (index in 0..numberOfSessions) {
if (index % 1000 == 999) { // added to test and understand when it's crashing
Timber.d("****** committing at ${index} sessions...")
realm.commitTransaction()
realm.beginTransaction()
}
val session = Session.newInstance(realm, false)
// Set Data
val calendar = Calendar.getInstance()
calendar.set(
(2017..2018).random(),
(0..11).random(),
(0..28).random(),
(0..23).random(),
(0..59).random()
)
val startDate = calendar.time
calendar.add(Calendar.HOUR_OF_DAY, (2..12).random())
calendar.add(Calendar.MINUTE, (0..59).random())
val endDate = calendar.time
session.startDate = startDate
session.endDate = endDate
session.result?.let { result ->
result.buyin = buyinList.random()
result.netResult = resultsList.random()
}
}
realm.commitTransaction()
}
realm.close()
} catch (e: Exception) {
Timber.e(e)
}
}
Проблема в том, что после 5000 сеансов на эмуляторе я получаю следующую ошибку:
I / art: поток [3, tid = 26297, ожидание в цепочке обработки сигналов, поток *= 0x9e560e00, одноранговый узел = 0x12cf79d0, «Перехватчик сигналов»]: реагирует на сигнал 3 A / libc: фатальный сигнал 11 (SIGSEGV), код 1, ошибка addr 0x65726e59 в tid 26292 (alytics.android) I / art: записал трассировки стека в ‘/data/anr/traces.txt «Приложение завершено.
Я не уверен, что это лучшая практика для вставки большого количества объектов в Realm.
Спасибо за вашу помощь!
Комментарии:
1.
SIGSEGV
означает нарушение памяти. Я предполагаю, что ваш код использует слишком много оперативной памяти в какой-то момент с циклами. Что-нибудь актуальное в/data/anr/traces.txt
?2. Кстати, вы делаете это
commitTransaction()
за пределами своего большого цикла. Это означает, что все 10000 транзакций загружаются в память до тех пор, пока не будут сброшены. Может быть причиной.3. Спасибо за комментарии! Я не уверен, что смотрю на правильный файл трассировок. Я использовал adb для его поиска, и файл всегда заканчивается системным идентификатором sdcard =1796″. Кроме того, в проводнике файлов моего устройства нет каталога «anr».
Ответ №1:
Вы сталкиваетесь с аварийным завершением работы ANR (приложение не отвечает) из-за блокировки основного потока. Основной причиной является эта строка:
Thread().run() {
// do work
}
Это не делает того, что вы думаете. Это инициализация Thread
, а затем выполнение блока кода с этим Thread
в качестве получателя. Однако на самом деле это не запуск Thread
— вместо этого ваш код выполняется в потоке пользовательского интерфейса.
Вместо этого вам нужно предоставить Runnable
вашему потоку и .start
его:
Thread {
// do your work in here
}.start() // this kicks off the thread and runs the block above asynchronously.
В качестве альтернативы, просто создайте исполнителя и отправьте свою работу:
Executors.newSingleThreadExecutor().submit {
// do your work in here
}