tgoop.com/gdb_dbg/220
Last Update:
Обещал тут порассказывать про свои самые злые кранчи. Кажется, сегодня просто идеально подходящий для этого вечер! (начинающаяся осенняя хандра, временное состояние отца-одиночки и просто миллион дел на эту неделю - атмосфера что надо).
---
Итак, кранч первый, пост-студенческий.
Немного контекста: в универе у меня был диплом про то, как сделать из консервативного сборщика мусора точный. В JVM со странным рантаймом, лишь наполовину написанном на managed языке, чём-то типа Java.
Опишу суть в паре предложений. Если супер упростить, то трассирующая сборка мусора в managed языке - это такой DFS: нужно выбрать объекты, которые 100% живы, и найти всех достижимых из них по ссылкам. Все, что вы не нашли - это и есть мусор. Есть небольшая проблемка: граф большеват - миллионы объектов, а обойти его нужно очень быстро - за миллисекунды. Отсюда и куча классных алгоритмов, как это делать эффективно, или по кускам, или параллельно с работой приложения, или еще как.
Но есть еще вопрос с тем, что такое "выбрать объекты, которые 100% живы". Как собственно это сделать? Ну, вот, например, локалы, которые еще будут использовать в будущем: ссылки в них то всяко живы, объекты, на которые они ссылаются - тоже. А как их найти в скомпилированном коде? На каких они регистрах, в каких стековых слотах? Тут есть два подхода:
1) Спросить у компилятора, он точно знает (он же этот код сгенерил!). Он вам может записать структуры данных, в которых будет сказано: "вот в этой точке в коде на rdx лежит ссылка на живой объект, начинай-ка разметку с нее". Понятны с этим проблемы: нужно тормозить треды только в этих специальных точках, а не где попало, для этих точек генерить какую-то метаинфу (а она ведь место занимает), и уже по ней GC будет находить гарантированно живые объекты,
2) Забить на компилятор. Консервативно предполагать, что любой регистр и любой стековый слот содержит указатель на объект, а потом (зная структуру памяти и особенности работы аллокатора) отсеивать всякий мусор. Так делают, когда хотят прикрутить GC к C++, например (там то откуда вам знать: лежит ли у вас на стеке просто чиселко или указатель, приходится падать в консерватизм).
Тут плюсы и минусы тоже понятны: с одной стороны никакой тебе метаинфы лишней и тормози треды (почти) где хочешь, с другой - консерватизм чреват ошибками. Объекты, которые давно померли могут быть признаны живыми, а это потенциально может привести к бесконечному потреблению памяти. Ну, как "потенциально", именно это и случалось у некоторых наших клиентов.
Собственно, что мне нужно было сделать: перейти от подхода консервативного GC, который по историческим причинам был у нас сделан, к точному GC. При этом постараться не слишком драматично просадить производительность, но главное - добиться корректности.
Это в свою очередь было не так просто в том числе и из-за хитрого рантайма, который лишь наполовину был написан на managed языке (там не так то просто гарантировать, что исполнение дойдет до safe-point за разумное время).
Ну и дополнительной сложностью было то, что такой работой никто в общем-то не занимается. Ну т.е. да, есть классические статьи Ole Agesen, где в общих чертах описано все, что нужно сделать. Но там a) нет кучи технических деталей, б) там рантайм то обычный, т.е. со многими основательными проблемами реализации никто и не сталкивался раньше (в SubstrateVM столкнулись, но у нас с ними получились прям разные решения).
Короче, задача то в целом довольно инженерная, совсем не rocket science, но чтобы ее сделать нужно просто огромный масштаб изменений провести в рамках кодовой базы JVM, прям с нуля ввести концепции, которых раньше в этой кодовой базе никогда и не было (хотя бы даже safe-points).
Так что в сумме (с перерывами на поход в enterprise и поиск себя) ушло у меня на это дело полтора года: половину на прототипирование (так появляется диплом бакалавра), половину на продуктизацию и решения проблем с рантаймом (так появляется диплом магистра).
Что-то не получилось рассказать контекст за пару предложений, но что поделать) Давайте переходить к кранчу ↓
#дух_машины
BY Алло, это отладочная?
Share with your friend now:
tgoop.com/gdb_dbg/220