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

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

Discussion in 'Разработка плагинов для новичков' started by CraftCoder, Jan 8, 2016.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Trophy Points:
    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 Старожил Пользователь

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Trophy Points:
    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 Старожил Пользователь

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

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

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

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

    Trophy Points:
    103
    Локация на то и локация.
     

Share This Page