Сборщик мусора для Android занимает слишком много времени - PullRequest
0 голосов
/ 16 октября 2019

Я сейчас работаю над приложением для Android в области компьютерной графики. Как вы, наверное, знаете, CG - это все о пикселях и векторах (в 3D).

Моя проблема в настоящее время заключается в том, что мне приходится вычислять несколько векторов для каждого пикселя (обычно около Full-HD: 1920 x 1080) несколько разВторой. Это оставляет меня с ... множеством Vec3D -объектов (по 32 байта каждый). Это не так много памяти (<100 МБ), но каким-то образом Android-сборщик мусора не может жить без очистки, которая занимает около 100 мс (безумно долго). </p>

Сначала я думал, что все эти объекты будут оптимизированыKotlin - Компилятор, поэтому я не беспокоился об этом при разработке - но, похоже, дело не в этом!

Как вы можете себе представить, большую часть времени GC работает вместо моего приложения. Я уже думал о Vec3D-Factory, который создает объект Vec3D -Object только один раз, но поскольку Vec3D использует три double переменные, я не думаю, что это слишком сильно изменится.

Есть идеи?

1 Ответ

1 голос
/ 16 октября 2019

Пулы обычно используются для минимизации создания экземпляров и сбора объектов. Вы можете создать базовый класс пула, например:

abstract class Pool<T> {
    private val objects = Stack<T>()

    protected abstract fun instantiate(): T
    protected abstract fun reset(obj: T)

    fun obtain(): T {
        return try {
            objects.pop()
        } catch (e: EmptyStackException){
            instantiate()
        }
    }

    fun free(obj: T){
        reset(obj)
        objects.push(obj)
    }

}

Затем создайте реализацию для типа объекта, который вы 'воссоздание:

class Vec3DPool : Pool<Vec3D>() {
    override fun instantiate(): Vec3D = Vec3D()

    override fun reset(obj: Vec3D) {
        obj.apply {
            x = 0.0
            y = 0.0
            z = 0.0
        }
    }
}

Затем, всякий раз, когда вам нужен новый объект, вызывайте pool.obtain() вместо создания нового. Всякий раз, когда вы закончите с объектом, возвращайте его в пул с pool.free() до того, как его ссылка будет потеряна. Бассейн будет висеть на нем, поэтому GC не будет срабатывать.

...