- Баллы
- 108
- Имя в Minecraft
- CraftCoderr
При отгрузке мира с помощью Bukkit.unloadWorld старый объект мира не выгружается из памяти, т.е. происходит утечка ОЗУ. Кто-нибудь знает как лечить это? Проблема в ведре или где-то у меня?
Все работало, но недавно все опять сломалось, причем теперь проблема еще глубже:

Как видно, все ссылки на объект мира циклические и среди них нет Location и т.п., но я не уверен, что WorldServer тоже, т.к. там слишком много полей, чтобы их просмотреть, поэтому проблема скорее всего в нем, иначе даже не могу предположить.
Вопрос: как решить? как убедится в предположении?
Решение:
После всех необходимых манипуляций с баккит объектом нужно удалить ссылку на мир из WorldServer:
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);//но по другому не работает
}
}
}
}
Все работало, но недавно все опять сломалось, причем теперь проблема еще глубже:
Как видно, все ссылки на объект мира циклические и среди них нет 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
}
Последнее редактирование: