tgoop.com/gdb_dbg/462
Last Update:
Разгадка на самом деле очень простая.
Что за тест:
К сожалению это был один из тех откровенно ублюдочных тестов, которые проверяют, что объект, который стал недостижим, будет собран GC.
Работает по очень простой схеме: создаем объект с финализатором, записываем единственную ссылку на него в локал => перетираем эту ссылку каким-нибудь другим значением => крутимся в цикле и ждем, пока финализатор сработает.
—
Почему тест ублюдочный:
Не существует никаких гарантий, что недостижимый объект будет собран. Про GC вообще почти ничего не говорится в спеке, например, языка Java. Это такое секретное внутреннее знание, что трассирующие GC вот так должны работать, но бывают исключения.
Например: обычно во время своей работы GC находит множество корневых объектов, используя информацию от компилятора. Дескать вот здесь, в этой точке на r14
лежит живая ссылка на объект, значит ты этот объект добавляй в корневое множество и размечай.
Но иногда GC может строить корневое множество поконсервативнее: смотреть на все регистры и слоты стека, находить там что-то похожее на ссылки и соответствующие объекты якорить. Это не очень надежно (как мы увидим чуть ниже), но все еще корректно.
Именно в этом методе была такая ситуация: корневое множество строилось консервативно.
—
Что произошло (почему зависало):
На r14
оставалась ссылка на объект, который на самом деле уже помер. Это мы в исходном коде перетерли ссылку на него, далеко не факт, что после всех оптимизация, она моментально ушла и из r14
.
Дальше крутимся в цикле, ждем срабатывание финализатора, а его все нет (GC раз за разом признает объект живым из-за этой протухшей ссылки на r14
). Вот вам и зависание.
Что произошло (почему перестало зависать):
За этот месяц в компиляторе проделали большую работу, которая к сожалению в том числе привела к появлению ненужной пересылки. Вместо того, чтобы записать 0
сразу в [rbp+0x18]
, компилятор сначала услужливо сохранил его на r14
. Имеет право, ведь r14
уже не используется, объект то мертв!
Это, конечно, пессимизация чистой воды, которую надо чинить. Но нашу то проблему это полечило! Ведь больше в r14
нет ссылки на мертвый объект, там нолик. Так что GC объект собирает, финализатор срабатывает, тест проходит.
—
Что было дальше:
Посмеялся, показал компиляторщикам, они очень возмутились, говорят, что надо срочно чинить! А я отвечаю: зачем, отличная работа, вы же баг починили 😂
Ну это шутка, на самом деле нужно здесь гасить консерватизм, мы это сделаем (он вообще случайно здесь вылез). Это то, конечно, просто плохой тест, но такое и в реальных приложениях может сослужить плохую службу и привести к неограниченному потреблению памяти. Рассказывал про это, например, вот здесь.
—
Паззлер первым разгадал @sergey_kachkin, респект!
#дух_машины
BY Алло, это отладочная?

Share with your friend now:
tgoop.com/gdb_dbg/462