Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

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

Тема в разделе "Разработка плагинов для новичков", создана пользователем CraftCoder, 8 янв 2016.

  1. Автор темы
    CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    При отгрузке мира с помощью Bukkit.unloadWorld старый объект мира не выгружается из памяти, т.е. происходит утечка ОЗУ. Кто-нибудь знает как лечить это? Проблема в ведре или где-то у меня?
    Код:
    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:
    Код:
            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
            }
    
     
    Последнее редактирование: 3 апр 2016
  2. Хостинг MineCraft
    <
  3. Code

    Code Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    _Gizmo
    откуда знаешь, что не выгружается? и почему он вообще должен выгрузиться?
     
  4. Автор темы
    CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Дамп памяти показывает, что с каждой огрузкой и дальнейшей подгрузкой одного и того же мира использование ОЗУ значительно возрастает. А почему он не должен отгружаться? Если я его выгружаю с сервера зачем ему оставаться в памяти?
     
  5. Larin

    Larin Старожил Пользователь

    Баллы:
    103
    А gc сработал или нет?
     
  6. Автор темы
    CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Да, gc() срабатывает. Причем ситуация тут такая: на линуксе память вообще никогда не очищается от этих старых миров, разве что при перезагрузке сервера. На винде память по началу вроде бы отгружается(в мониторинге ресурсов показывает уменьшение использования ОЗУ), но это не так, память остается замусорена и когда замусоривается вся память, то в мониторинге процессов отображается, что java приложение имеет кучу ошибок при попытки обращения к памяти.
     
  7. Larin

    Larin Старожил Пользователь

    Баллы:
    103
    Зачем ты диспетчер задач используешь? Для java профайлеры используют, вот там и увидишь, сработал gc или нет.[DOUBLEPOST=1452269632,1452269602][/DOUBLEPOST]Also, используй sponge и всё. Он уже в бете.
     
  8. Автор темы
    CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Работу gc я отслеживаю через visualVm и он срабатывает.
     
  9. Larin

    Larin Старожил Пользователь

    Баллы:
    103
    А если оттуда вызвать сбор?
    ----
    Параметры запуска?
    Версия?
    Плагины?
    Версия jvm?
     
  10. Автор темы
    CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    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 последняя[DOUBLEPOST=1452272585,1452272535][/DOUBLEPOST]@Shevchik @fromgate
     
  11. Larin

    Larin Старожил Пользователь

    Баллы:
    103
    На других версиях были проблемы такие? Пробовал без +UseParNewGC?
     
  12. Автор темы
    CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    На других версиях не пробовал. Попробую запускать без UseParNewGC
     
  13. Shevchik

    Shevchik Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Никак это почти не лечится, слишком много всего внутри самого майнкрафт сервера держит сильные ссылки на мир.
     
  14. Автор темы
    CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Пишут, что на версии 1.7 этой проблемы не было.[DOUBLEPOST=1452352363,1452316907][/DOUBLEPOST]UP!
     
  15. Larin

    Larin Старожил Пользователь

    Баллы:
    103
    Создавай issue на сайте спигота.
     
  16. Code

    Code Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    _Gizmo
    да там есть уже и отвечают каку-то шнягу крафткодеру)
     
  17. Larin

    Larin Старожил Пользователь

    Баллы:
    103
    Не нашел этой темы в issue tracker'е
     
  18. Автор темы
    CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    https://hub.spigotmc.org/jira/browse/SPIGOT-651
    https://www.spigotmc.org/threads/memory-leak-unloading-a-world-causes-huge-memory-leaks.30505/[DOUBLEPOST=1452441915,1452356717][/DOUBLEPOST]UP[DOUBLEPOST=1452615004][/DOUBLEPOST]Перед отгрузкой мира я убираю все ссылки на объект мира, но не убираю ссылки на локации... Может быть из-за этого?
     
  19. Larin

    Larin Старожил Пользователь

    Баллы:
    103
    Ну дурак! Конечно же! Там есть объект типа World.
     
  20. Автор темы
    CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    абидна (((( Сейчас буду пробовать исправить, если дело в этом, то сделаю небольшое апи и выложу сюда.
    P.S. Думал до меня о локациях позаботились((((
     
    Последнее редактирование: 12 янв 2016
  21. Larin

    Larin Старожил Пользователь

    Баллы:
    103
    Локация на то и локация.
     

Поделиться этой страницей