NativeImage душит память

Сообщения
163
Лучшие ответы
8
Реакции
25
Версия Minecraft
1.13+
В 1.13 на смену BufferedImage пришел майновский NativeImage и мне изначально показалось, что здесь не может быть никаких проблем, но как бы не так.

Мой код подгружает несколько изображений на игрока из интернетов и при помощи DynamicTexture регистрирует их в игре. И если раньше(1.12.2) такой код почти не оказывал сильного влияния на память, то с пришествием 1.13 начался ад. Отныне жрется от 6 до 40мб на один экземпляр DynamicTexture, в зависимости от качества картинки(использую весом до 200кб). Мало того, это память теперь еще и не хочет чиститься GC. Даже если вызвать close(), GC не скоро удаляет такие объекты и за процессом при 10-20 загрузках на минуту висит от 1гб лишней памяти...
Прошу помощи у знающих людей, ибо сам уже отчаялся. Не хочется изобретать свою NativeImage

Важно: проблема точно определена. Тот же код, но на базе BufferedImage работает исправно.

Java:
            for (int i = 0; i < 30; i++) {
                ResourceLocation res = new ResourceLocation("cornell_test_" + i);
                NativeImage image;
                try {
                    image = MinecraftUtils.readNativeImage(new URL("my_url").openStream());
                    DynamicTexture dynamicTexture = new DynamicTexture(image);
                    Minecraft.getMinecraft().getTextureManager().loadTexture(res, dynamicTexture);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
Последнее редактирование:
Сообщения
5,311
Лучшие ответы
173
Реакции
946
Сообщения
2,488
Лучшие ответы
77
Реакции
371
Немного глянул код. Никаких проблем в NativeImage и DynamicTexture нет. Просто ты ими не правильно пользуешься.

Во-первых, в NativeImage память нужно очищать вручную (вызвать метод close()). Соответственно, т.к. DynamicTexture хранит NativeImage, то его тоже нужно очищать самостоятельно. А ты, скорее всего, создаешь DynamicTexture, кладешь её в TextureManager и забываешь. При перезагрузке текстур, конечно же, ничего не очищаешь и создаешь еще один DynamicTexture. Поэтому течёт память.

Во-вторых, DynamicTexture вообще не нужен. DynamicTexture хранит текстуру не только в видеопамяти, но и держит её в оперативе для того, чтобы можно было динамически менять текстурку и перезагружать в видеопамять. Скорее всего тебе это не нужно. Поэтому стоит написать свою реализацию Texture, подобную DynamicTexture, но без хранения NativeImage.
 
Сообщения
42
Лучшие ответы
0
Реакции
6
В джаве (и, боже, в более низкоуровневых языках) принято закрывать, то что открыл. Почитай про try-with-resources.
Сам открыл - сам закрой. Сам не открывал - не закрывай.
 
Сверху