Войти или зарегистрироваться

[Решено]Отгрузка мира с помощью Bukkit.unloadWorld

CraftCoder

Старожил
Пользователь
Баллы
108
Имя в Minecraft
CraftCoderr
При отгрузке мира с помощью Bukkit.unloadWorld старый объект мира не выгружается из памяти, т.е. происходит утечка ОЗУ. Кто-нибудь знает как лечить это? Проблема в ведре или где-то у меня?
Java:
for (TileEntity tileEntity : ((CraftWorld) world).getHandle().tileEntityList)
        {
            if (tileEntity instanceof IInventory)
            {
                Iterator<HumanEntity> entityIterator = ((IInventory)tileEntity).
                        getViewers().iterator();
                while (entityIterator.hasNext())
                {
                    HumanEntity human = entityIterator.next();
                    if ((human instanceof CraftPlayer) &&
                            !((CraftPlayer) human).isOnline())
                    {
                        entityIterator.remove();//по сути это одно и то же
                 ((IInventory)tileEntity).onClose(human);//но по другому не работает
                    }
                }
            }
        }

Все работало, но недавно все опять сломалось, причем теперь проблема еще глубже:
Снимок.PNG Снимок2.PNG
Как видно, все ссылки на объект мира циклические и среди них нет Location и т.п., но я не уверен, что WorldServer тоже, т.к. там слишком много полей, чтобы их просмотреть, поэтому проблема скорее всего в нем, иначе даже не могу предположить.
Вопрос: как решить? как убедится в предположении?

Решение:
После всех необходимых манипуляций с баккит объектом нужно удалить ссылку на мир из WorldServer:
Java:
        try
        {
            WorldServer w = ((CraftWorld) world).getHandle();
            Field f = UtilReflection.getField(w.getClass().getSuperclass(), "world");
            f.setAccessible(true);
            f.set(w, null);
            f.setAccessible(false);
        } catch (Exception e)
        {
            //shutdown
        }
 
Последнее редактирование:
При отгрузке мира с помощью Bukkit.unloadWorld старый объект мира не выгружается из памяти, т.е. происходит утечка ОЗУ. Кто-нибудь знает как лечить это? Проблема в ведре или где-то у меня?
откуда знаешь, что не выгружается? и почему он вообще должен выгрузиться?
 
откуда знаешь, что не выгружается? и почему он вообще должен выгрузиться?
Дамп памяти показывает, что с каждой огрузкой и дальнейшей подгрузкой одного и того же мира использование ОЗУ значительно возрастает. А почему он не должен отгружаться? Если я его выгружаю с сервера зачем ему оставаться в памяти?
 
Дамп памяти показывает, что с каждой огрузкой и дальнейшей подгрузкой одного и того же мира использование ОЗУ значительно возрастает. А почему он не должен отгружаться? Если я его выгружаю с сервера зачем ему оставаться в памяти?
А gc сработал или нет?
 
А gc сработал или нет?
Да, gc() срабатывает. Причем ситуация тут такая: на линуксе память вообще никогда не очищается от этих старых миров, разве что при перезагрузке сервера. На винде память по началу вроде бы отгружается(в мониторинге ресурсов показывает уменьшение использования ОЗУ), но это не так, память остается замусорена и когда замусоривается вся память, то в мониторинге процессов отображается, что java приложение имеет кучу ошибок при попытки обращения к памяти.
 
Зачем ты диспетчер задач используешь? Для java профайлеры используют, вот там и увидишь, сработал gc или нет.
Also, используй sponge и всё. Он уже в бете.
 
Зачем ты диспетчер задач используешь? Для java профайлеры используют, вот там и увидишь, сработал gc или нет.
Also, используй sponge и всё. Он уже в бете.
Работу gc я отслеживаю через visualVm и он срабатывает.
 
А если оттуда вызвать сбор?
----
Параметры запуска?
Версия?
Плагины?
Версия jvm?
Java HostSpot 64-bit Server VM (jre 1.8.0_66)
-Xincgc -Xmx512M -XX:MaxPermSize=128M -XX:+UseParNewGC -Dfile.encoding=UTF-8 -jar spigot.jar
Плагины protocollib, anticheatadvanced, мои плагины(отгрузка мира сделано с помощью Bukkit.unloadWorld)
Версия сервер spigot 1.8.9 последняя
@Shevchik @fromgate
 
Java HostSpot 64-bit Server VM (jre 1.8.0_66)
-Xincgc -Xmx512M -XX:MaxPermSize=128M -XX:+UseParNewGC -Dfile.encoding=UTF-8 -jar spigot.jar
Плагины protocollib, anticheatadvanced, мои плагины(отгрузка мира сделано с помощью Bukkit.unloadWorld)
Версия сервер spigot 1.8.9 последняя
@Shevchik @fromgate
На других версиях были проблемы такие? Пробовал без +UseParNewGC?
 
Никак это почти не лечится, слишком много всего внутри самого майнкрафт сервера держит сильные ссылки на мир.
 
Создавай issue на сайте спигота.
 
https://hub.spigotmc.org/jira/browse/SPIGOT-651
https://www.spigotmc.org/threads/memory-leak-unloading-a-world-causes-huge-memory-leaks.30505/
UP
Перед отгрузкой мира я убираю все ссылки на объект мира, но не убираю ссылки на локации... Может быть из-за этого?
Ну дурак! Конечно же! Там есть объект типа World.
 
Ну дурак! Конечно же! Там есть объект типа World.
абидна (((( Сейчас буду пробовать исправить, если дело в этом, то сделаю небольшое апи и выложу сюда.
P.S. Думал до меня о локациях позаботились((((
 
Последнее редактирование:
Назад
Верх