1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Это баг или я совсем не понимаю Java?

Тема в разделе "Оффтопик", создана пользователем GloomyFolken, 6 дек 2013.

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

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

    Баллы:
    103
    Skype:
    alconost
    Умные люди, объясните суть лога! Как может быть вылет за границы массива на индексе 3999, если размер - 4000? Какой-то очень-очень редкий баг или я чего-то не понимаю?
    Код:
    2013-12-06 20:59:10 [INFO] [STDERR] java.lang.IndexOutOfBoundsException: Index: 3999, Size: 4000
    2013-12-06 20:59:10 [INFO] [STDERR]     at java.util.ArrayList.rangeCheck(Unknown Source)
    2013-12-06 20:59:10 [INFO] [STDERR]     at java.util.ArrayList.get(Unknown Source)
    2013-12-06 20:59:10 [INFO] [STDERR]     at net.minecraft.client.particle.EffectRenderer.renderParticles(EffectRenderer.java:118)
    2013-12-06 20:59:10 [INFO] [STDERR]     at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1262)
    2013-12-06 20:59:10 [INFO] [STDERR]     at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:991)
    2013-12-06 20:59:10 [INFO] [STDERR]     at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:871)
    2013-12-06 20:59:10 [INFO] [STDERR]     at net.minecraft.client.Minecraft.run(Minecraft.java:760)
    2013-12-06 20:59:10 [INFO] [STDERR]     at java.lang.Thread.run(Unknown Source)
    
     
  2. msgroup

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

    Баллы:
    153
    Skype:
    vladcygankov
    Имя в Minecraft:
    msgroup
    Наверное твой массив начинается с 0 и заканчивается 3999, что и составляет эти 4000.
     
    BleaZzZ нравится это.
  3. Holod

    Holod Активный участник Пользователь

    Баллы:
    93
    Массив размера 4000 это массив [0..3999]
    3999 элемент есть, а вот 4000 нету.
    Скорее всего вылет на 3999 итерации при попытке обращения к следующему элементу.
     
  4. Автор темы
    GloomyFolken

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

    Баллы:
    103
    Skype:
    alconost
    Ну да, я (то есть майн) обращаюсь к 3999 элементу и вылетаю за границы. При последнем элементе в 3999.

    А почему если оно пытается обратиться к следующему элементу, то индекс, с которым вылетает - 3999? Если оно при итерации вылетает за границы, то ошибка - (Index: X, Size: X)
     
  5. Holod

    Holod Активный участник Пользователь

    Баллы:
    93
    Это уже код надо смотреть.
    Может кто-то написал цикл:
    for (int i = 0; i <= arr.length; i++) {...}
     
  6. Автор темы
    GloomyFolken

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

    Баллы:
    103
    Skype:
    alconost
    Код:
     for (int j = 0; j < this.fxLayers[i].size(); ++j)
                    {
                        EntityFX entityfx = (EntityFX)this.fxLayers[i].get(j); //тут ошибка
                        if (entityfx == null) continue;
                        tessellator.setBrightness(entityfx.getBrightnessForRender(par2));
                        entityfx.renderParticle(tessellator, par2, f1, f5, f2, f3, f4);
                    }
    У нас поверх массива еще arraylist. С чистым массивом это вряд ли связано. Вот я и думаю на какую-то особенность ArrayList'a.
    ________________________________-
    Да и код этот вызывается каждый тик при рендеринге частиц. Странно было бы увидеть тут дурацкую ошибку. А если поставить "не меньше" вместо "больше", то ошибка выглядит как "Индекс: Х, размер: Х". Тут - "Индекс: Х-1, размер: Х".
     
  7. Holod

    Holod Активный участник Пользователь

    Баллы:
    93
    Выглядит код годно.
    Может из другого потока какой-то метод удалил элемент листа fxLayers[i]

    Можно кстати foreach'ем пробежать. Не помню в java какой синтаксис у него.
     
    GloomyFolken нравится это.
  8. Автор темы
    GloomyFolken

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

    Баллы:
    103
    Skype:
    alconost
    Это - код майнкрафта. Он корректно отработал миллиарды, или даже триллионы раз. foreach выглядит так:
    Код:
    for (EntityFX entityFX:this.fxLayers[i])
      {
      //код
      }
    Проблема в том, что в триллион первый раз этот код отработал неправильно. Идея с потоком мне кажется вполне реальной. Не знаю, как это могло произойти с однопоточной логикой майнкрафта, но больше ничего в голову не приходит.
     
  9. caNek

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

    Баллы:
    173
    Имя в Minecraft:
    AddyCool
    0=1
    3999=4000
     
  10. Автор темы
    GloomyFolken

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

    Баллы:
    103
    Skype:
    alconost
    Я понимаю, что 99% начинающих кодеров на это натыкаются, и рефлекс на вопрос про массивы и пару чисел (X) и (Х-1) у всех выработался такой. Но, блин, почитай тему внимательнее! Здесь идет обращение к 3999-му элементу массива в 4к элементов. Последнему, но существующему.
    Разобрался в коде, правда связано с многопоточным ковырянием ArrayList'a. Всем спасибо.
     
  11. Shevchik

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

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Ковырять листы в нескольких потоках - да ты рисковый парень.
     
    skynetxxx нравится это.
  12. Автор темы
    GloomyFolken

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

    Баллы:
    103
    Skype:
    alconost
    Названия пакетов почитай =/
    Майн ковыряет лист с частицами в нескольких потоках (изменяет в логике, читает в рендеринге). Поэтому, если рисовать из них что-то серьезное (эксперементировал с этим), то он с хорошей вероятностью падает.
     
  13. Shevchik

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

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Круто фигли, на малых массивах не падает, ибо считаться успевает полностью, а баг никто в ванильном майне и не заметит никогда я думаю. В любом случае эту фигню на CopyOnWriteArrayList менять надо.
     
  14. Автор темы
    GloomyFolken

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

    Баллы:
    103
    Skype:
    alconost
    Угу, на весь инет три с половиной таких лога, и никто даже не разобрался, что в них написано. CopyOnWriteArrayList - тоже не замечательный вариант. При таком количестве частиц, что появляется этот баг, он будет кушать слишком много ресурсов. Для себя я "решил" проблему установкой блоков try-catch в коде для потоке рендеринга. Не настолько важна каждая частица, чтоб так железо ради нее мучать. Не отрендерится - так не отрендерится. Но вот плагины с огромным количеством частиц не написать =(
     

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