АСУ ТП — тухлая отрасль, надо идти в IT?

Отлаживаем и запускаем насосную станцию ВЗУ
Отлаживаем и запускаем насосную станцию ВЗУ

Довольно часто я слышу такое мнение среди своих коллег и сотрудников, и, будем честными, на то есть причины.

АСУ ТП (автоматизированные системы управления технологическими процессами) — это когда у вас большое предприятие, конвейер, производство, очистные сооружения или что-то подобное и вам нужно отладить весь процесс в автоматическом режиме, чтобы все работало без участия человека, а человек только наблюдал на большом мониторе. Сюда же относится и инфраструктура здания: вентиляция, отопление, свет, вода, учет и т. д. Все эти системы можно объединить более емким словом — АСУ. И так как я работаю в основном именно в области инфраструктуры зданий, то дальше речь пойдет о ней.

Что не так с АСУ, с точки зрения программиста? Сложный и объемный фронт работы, при этом невысокие зарплаты. Программист на объекте чаще всего и швец, и жнец, и на дуде игрец. Помимо процесса разработки программного обеспечения, он обязан также понимать сам процесс, который автоматизирует. Необходимо разбираться в датчиках, исполнительных механизмах и нюансах процесса. Нужно уметь читать электрические схемы и разбираться во всех внутренностях шкафа управления, находить нестыковки в проекте и сборке. Добавим сюда панель оператора, на нее тоже нужно написать программу и увязать с алгоритмом. Надо разработать верхний уровень, установить SCADA-систему, настроить базу данных, отчеты, графики, написать кучу скриптов, увязать опять-таки с алгоритмом и с панелью оператора. Не забываем про сетевую инфраструктуру, коммутаторы, свичи и т. д. Добавим еще и графический интерфейс для панели и для SCADA-системы. По-хорошему этим должны заниматься несколько специалистов, но в реальности все делает именно программист, используя готовые библиотеки для экономии времени. Почему так происходит, я писал в этой статье. Стоит еще обязательно сказать о том, что редко компания работает только с одним вендером, чаще это 2-4 разных производителя железа и софта, отсюда разные среды разработки и разные языки, разные нюансы и подходы. Многовато выходит, да? И это все делается в полевых, не самых комфортных условиях, не в уютном офисе и точно не в кафешке. Даже перечислять непросто, а разобраться во всем одному человеку и довести до рабочего состояния крайне сложно, притом что вилка зарплаты — 80-150 тыс. р.

Что не так с АСУ, с точки зрения предпринимателя? Крайне сложно продать свои услуги дорого. Почему-то так сложилось, что вся эта работа стоит существенно дешевле, чем она должна стоить. Каждый раз приходится объяснять и обосновывать, почему заказчик должен заплатить за то или иное.

Звучит все это не очень перспективно, да? Прямо-таки антиреклама отрасли. Не знаю, как там сейчас у айтишников, но кажется, что их час работы оценивается прилично дороже. Мы же имеем что имеем, и нужно что-то делать и учиться работать с тем, во что уже влип по уши. На мой взгляд, есть тонкости и ошибки, над которыми стоит поработать, если вы предприниматель, руководитель или фрилансер, чтобы ваши услуги стоили дороже.

Давайте разбираться по порядку. Нужно понимать, что мы технари и общаемся и договариваемся тоже с технарями. Мы общаемся на техническом языке и решаем технические задачи. А технический язык — это не совсем про деньги. Я могу ошибаться, и наверняка есть исключения, но моя практика показывает именно это. Для примера: стоит задача — автоматизировать кондиционеры в офисе, вывести на удаленное управление и расставить несколько датчиков, контролировать температуру и влажность. Обсуждая с эксплуатацией эту задачу, вы будете решать, где ставить сервер, датчики, как тащить кабель, как сделать локалку, какие данные собирать и какой софт использовать. Так как монтаж кабеля, установка и настройка не могут быть дорогими, то выставить высокую цену будет сложно, придется искусственно раздувать и накручивать стоимость, а это неправильно.

Напрашивается выводы: нужно переходить с технического языка на язык маркетинга. Можно начать с банальной подмены слов. Понятия «объект» и «заказчик» давайте оставим строителям, а мы будем использовать «проект» и «клиент». Слова «монтаж» и «установка» тоже оставим там же, будем говорить «реализация» и «интеграция». Перефразируем нашу задачу так: проект мониторинга микроклимата офисного пространства и повышение общей энергоэффективности инженерных систем. Уже звучит интересно и для нас, и для клиента.

Идем дальше. Всю внутреннюю кухню по реализации проекта давайте оставим внутри компании. Такие слова, как «интерфейс», «шлюз», Modbus, SCADA, ПЛК и т. д. , будем использовать между собой и не выносить за пределы. Нет смысла погружать клиента во все технические тонкости. У клиента (читаем — бизнеса) есть свои проблемы и задачи, которые нам необходимо решить. Как именно это будет происходить — дело третье.

Следующий вывод: клиенту нужны комплексный подход и готовое решение его проблемы. При этом само решение мы, скорее всего, будем разрабатывать под каждого клиента и задачу индивидуально, так как в нашей отрасли подготовить по-настоящему работающее коробочное решение крайне сложно. Например, к нам обратилось крупное производственное предприятие, которое по понятным причинам расходует очень много электроэнергии. Нас попросили сделать систему технического учета разных потребителей, чтобы можно было понять, как именно она расходуется, вследствие чего в будущем оптимизировать этот расход. С нашей стороны, задача не слишком сложная. Необходимо развесить трансформаторы, поставить анализаторы тока, прокинуть пару сотен метров кабеля, развернуть и настроить SCADA-систему. В этом случае клиенту вообще не стоит вникать в эти подробности. Ему надо, чтобы в определенный момент времени в нужном месте появлялись необходимые отчеты. Чаще всего ему неважно, на каком оборудовании и на каком софте будет реализован проект, и нам от этого проще. Назовем это пилотным проектом по оптимизации энергозатрат производства и представим как готовое решение под конкретную задачу клиента.Важно понимать, что стоимость коммерческого предложения для клиента будет формироваться не из затрат на материалы + ФОТ + налоги + прибыль, а именно как стоимость, которую бизнес готов заплатить за решение своей проблемы, чтобы он (бизнес) дальше продолжил заниматься решением своих проблем и зарабатывать больше денег.

Важно понимать, что стоимость коммерческого предложения для клиента будет формироваться не из затрат на материалы + ФОТ + налоги + прибыль, а именно как стоимость, которую бизнес готов заплатить за решение своей проблемы, чтобы он (бизнес) дальше продолжил заниматься решением своих проблем и зарабатывать больше денег.

Резюмирую. Мы сейчас внутри себя все автоматчики. Контроллеры, SCADA, HMI, Siemens, Schneider. Мы на процесс смотрим изнутри, и большинство, с кем мы работаем, тоже видит процесс изнутри. Нам нужно общаться с клиентами на принципиально ином языке. Рекламировать себя и давать информацию именно как компания, которая реализует комплексно сложные технические проекты (не объекты). Правильнее всего будет ориентироваться на топовые диджитал-студии, к которым обращаются крупные компании за их компетенцией и проектами под ключ. Мы должны позиционироваться так же, как профессионалы, решающие комплексные задачи. Когда идет работа такого плана, как заменить контроллер, запустить вентиляцию, собрать шкаф, — это здорово, и на таком можно зарабатывать. Но в долгосрочной перспективе этим заниматься неинтересно, и к росту это не приведет.

Есть еще один существенный плюс отрасли АСУ, который я стараюсь использовать в последнее время. Организовав правильно процесс, отдавая монтаж и сборочную работу на аутсорс, можно реализовывать действительно крупные и серьезные проекты очень маленькой командой инженеров, буквально из 2‐4 человек.


ссылка на оригинал статьи https://habr.com/ru/post/680144/

Вейп. Кто и чем травит наших детей

Не доверяйте подросткам! И не будете разочарованы

Недавно я нашёл у своего сына вейп, если кто не знает – это такой ингалятор или микрокальян для вдыхания никотина, при выдохе создаётся огромное облако пара, которое обычно имеет фруктовый запах. Вы наверняка видели на улицах подростков, которые, подобно пароходу, курсируют в клубах пара, и если из этого облака вы слышите вместо, вполне уместного ситуации пароходного гудка, четырёхэтажный мат, то ошибки быть не может – перед вами никакой не Крузенштерн человек и пароход, а самый настоящий вейпер.

Поначалу подумал: «Не может быть!», откуда у моего, умницы, спортсмена, комсомольца подобная дрянь? Зачем ЭТО ему нужно? Да и что может связывать моего самого любимого и лучшего в мире ребёнка с этими дегенератами из семей маргиналов?

Попытка поиграть с сыном в «что, где, когда» практически провалилась, ибо дитятя пояснил, мол, папа, успокойся, это просто сладкий водяной пар, в нём нет никакого вреда, у нас почти весь класс парит, вся самокатная площадка курит, и многим даже сами родители покупают вейпы и расходники к ним. И это… Неправильный ответ!

Личное пространство, говорили они, свобода, говорили они

Безумно доверяя своему сыну, я раньше никогда бы и не подумал войти в его социальные сети, но результаты конкурса, описанного в предыдущем абзаце, явно намекали, на необходимость открытия этого чёрного ящика. Не буду объяснять, как можно получить доступ к чужой странице ВК, методы могут быть самыми разнообразными – от банального входа с телефона – до получения пароля с помощью нейролингвистических практик, как бы то ни было, доступ мною был получен.

Не кривя душой, скажу честно, мой мир никогда не будет прежним. Организовав поиск по ключевым словам «жижа», «вейп», и т.п. для мне открылась нерадостная картина. Читать переписки было практически невозможно, т.к. от обилия обсценной лексики хотелось вымыть глаза, в моменты, когда я пытался осмыслить прочитанное, искренне жалел о том, что устройство «нейрализатор» из фильма Люди в чёрном, является лишь плодом фантазии сценариста.

Главное в следственных действиях — это не выйти на самих себя

Анализ переписок, опрос участвующих лиц и диалоги с их родителям, разговоры с завучем школы по воспитательной работе, где обучается мой сын, показали:

  • по моим оценкам, около 30% подростков в том или ином виде потребляют никотиносодержащую продукцию;

  • дети от вейпа на короткое время входят в состояние, сравнимое с наркотическим опьянением;

  • самому младшему из установленных участников 9 лет (второй класс);

  • жидкости для вейпа (жижа) и аксессуары для курения практически беспрепятственно продаются детям и подросткам;

  • дети на площадках объявлений ВК продают и покупают вейпы и аксессуары к ним;

  • несовершеннолетние могут беспрепятственно заказывать вейпы и аксессуары к ним через площадки OZON и WILDEBERRIES;

  • в социальных сетях активно ведется торговля бывшей в употреблении жидкости для вейпов, а также самостоятельно изготовленными в кустарных условиях жидкостями (самозамесы);

  • подростки, употребляющие никотин, склонны к употреблению алкоголя и тяжелых психотропных средств;

  • подростки неинформированны или плохо информированны о последствиях употребления никотиносодержащей продукции;

  • немедленное токсическое воздействие электронных сигарет намного превышает токсическое воздействие обычных сигарет.

Картина печальная!

Да ну! Бред какой-то!

Ещё несколько дней назад я бы тоже подумал, что всё это выдумки, но спорить с фактами бессмысленно. Школьные туалеты и комнаты в детских лагерях превратились в кальянные, любой педагог, работающий с детьми, подтвердит вам это, и ладно бы от данной проблемы страдали только дети с никотиновой зависимостью, остальные невольно становятся пассивными курильщиками, а многие, не имея возможности избежать фактов употребления, ведясь на сказки про безвредность и красивые картинки, становятся активными потребителями.

Риски для здоровья от вейпинга: наркотическая зависимость, тревога и депрессия, бессоница, импотенция, рак, хронический бронхит, повреждение легких (kidshealth)

Вейп – это безобидное увлечение

Как бы не так, употребляя вейп, можно приобрести никотиновую зависимость, получить риск развития аллергических реакций и астмы, подхватить воспаление дыхательных путей, отравиться никотином, отправиться на тот свет от редкой пока на наших просторах болезни EVALI (e-cigarette, or vaping, product use associated lung injury), про негативное влияние никотина на сосуды и риск развития рака можно не говорить, уверен, об этом и так все знают. К слову, всё это краткосрочные эффекты от парения, долгосрочное влияние на здоровье человека требует дальнейшего изучения.

Знаю, что многие захотят поспорить с моими доводами, основываясь на личном опыте использования вейпа, не являясь экспертом в области медицины, могу порекомендовать жадным до дискуссий адептам безопасного парения, сойтись в словесной дуэли с авторами статей о влиянии потребления вейпов и электронных сигарет на организм человека журнала THE LANCET (один из наиболее известных, старых и самых авторитетных журналов по медицине). Можно пойти ещё дальше и опубликовать свои независимые исследования. Ссылки на материалы я привожу ниже.

Эксперты в статьях утверждают, что смертность от EVALI около 2.5%, а симптомы судя по описанию, во многом похожи на COVID-19, кроме того, потребители вейпа и электронных сигарет имеют в 5-7 раз больше шансов заболеть COVID-19. Врачи бьют тревогу ввиду того, что в связи с ростом популярности «электронных средств доставки никотина» (подразумевают вейпы и электронные сигареты) в несколько раз выросло потребление никотина среди молодёжи, в тех же исследованиях говорится о том, что никотин повреждает развивающийся мозг детей и подростков.

Ссылаясь на эти данные, в США ужесточили законодательство о продаже никотиносодержащей продукции, увеличив возраст приобретения до 21 года, а небезызвестная компания APPLE удалила все приложения для вейперов из своего App Store в 2019 году.

так выглядит лозунг "мы не хотим, чтобы вейп-продукция привлекала детей"
так выглядит лозунг «мы не хотим, чтобы вейп-продукция привлекала детей»

Наших детей травят сознательно!

Достаточно посмотреть на красочную обёртку с мультяшными персонажами, в которую упакована эта самая никотиносодержащая жидкость, добавьте к этому сладкий вкус, вдыхаемого потребителем, не забудьте про визуальную составляющую, про неестественно плотные клубы пара, про разговоры о почти полной безвредности, отсутствие характерного сигаретного запаха на руках и одежде, а также про модный электронный прибор в кармане. Разве похоже, что это предназначается взрослому человеку? Не смешите! Вспомните, как продаются сигареты и что нарисовано на упаковке, как продают сигареты. Вот уже несколько лет в магазинах невозможна открытая демонстрация сигаретных пачек, а на самих пачках красуются наглядные материалы, демонстрирующие потенциальную опасность употребления. Так почему же всё, что связано с вейпами продаётся совершенно открыто и практически без предупреждения о вреде здоровью?

а так выглядят пачки с сигаретами, чувствуете разницу?
а так выглядят пачки с сигаретами, чувствуете разницу?

Что делать?

Допускаю, что власти малоинформированы о существующей проблеме, в таком случае, ответственным за социальную политику и здоровье лицам, необходимо выйти из тёплых кабинетов и прогуляться в сторону школ и мест скопления молодёжи, увиденное не должно им понравиться. И что делать, как можно повлиять на сложившуюся ситуацию?

Могу высказать свои мысли и предложения:

  • запретить или ограничить продажу никотиносодержащих жидкостей, используемых для вейпинга;

  • установить предельный лимит концентрации никотина в никотиносодержащих жидкостях;

  • увеличить возраст продажи никотиносодержащей продукции и средств ее употребления гражданам, не достигшим 21 года;

  • запретить демонстрацию и рекламу никотиносодержащей продукции и средств ее употребления;

  • запретить продажу никотиносодержащей продукции и средств ее употребления удаленно;

  • ужесточить ответственность за нарушение правил торговли никотиносодержащими средствами;

  • повысить информированность населения о вреде употребления электронных сигарет и вейпов;

  • в школах ввести обязательное или по согласию с родителями анонимное тестирование на никотин, результаты доводить до сведения опекунов ребёнка;

  • оборудовать туалеты детских учреждений детекторами пара и дыма;

  • лиц, уличенных в употреблении никотиносодержащей продукции на территории детских учреждений, привлекать к ответственности;

  • лиц, участвующих в продаже никотиносодержащей продукции несовершеннолетним, подвергать линчеванию (шутка), что с ними делать я не знаю, пишите в комментариях, но, я уверен, наказание должно быть максимально строгим.

Эти, по своей сути небольшие, изменения в законодательстве не нанесут негативного влияния на экономику страны, как и не ущемят прав взрослых пользователей вейпов, но при этом позволят сократить число наркозависимых и больных граждан.

Вместо заключения

Я не замечал данной проблемы до момента, пока она не коснулась меня лично, в попытках разобраться в причинах, я быстро обнаружил, что независимо от пола ребенка, благосостояния семьи, уровня образования родителей, успеваемости подростка в школе, он с легкостью может стать активным потребителем никотина. В классе моего сына (9-й класс) около 30% употребляют никотин с помощью вейпов, или в виде никотиносодержащих жевательных смесей (снюсы), в некоторых параллельных классах процент потребителей и того больше.

Законодательная власть не видит надвигающейся угрозы, если мы, активные граждане, патриоты своей страны, люди, которым небезразлична судьба подрастающего поколения не займемся решением сейчас, то завтра может быть поздно. Количество потребителей никотина среди молодежи за последние годы выросло в несколько раз. В данной статье речь идет о городе Белгород, но место событий неважно, в других регионах ситуация ничуть не лучше, более того, это мировая тенденция.

Я работаю в одной из крупнейших IT-организаций нашей страны, по долгу службы мне приходится собеседовать студентов ВУЗов, чтобы в дальнейшем дать им настоящую, интересную, высокооплачиваемую работу. Увы, качество подготовки специалистов падает, а встречи и доверительные беседы с лицами, ответственными за подготовку, показали, что основная проблема – это среда, в которую попадает молодежь.

Почти все мои друзья и даже супруга заявили мне, что я, подобно Дон Кихоту Сервантеса, пытаюсь бороться с ветряными мельницами, но мой характер и жизненная позиция не позволяют оставаться в стороне, подключайтесь и вы. Идеи и предложения оставляйте в комментариях, я систематизирую эту информацию и постараюсь донести до представителей законодательной власти.

Спасибо, что дочитали до конца.

Материалы

BioMed Central

The Lancet:

Kids health:


ссылка на оригинал статьи https://habr.com/ru/post/680074/

Стабилизатор по швейцарски. Гидроаккумулятор на 20 млн кВтч

Два кристально чистых голубых озера в швейцарском кантоне Вале, Лак-д’Эмоссон и Лак-дю-Вьё-Эмоссон, на первый взгляд выглядят как множество местных ледниковых озёр, окружённых горами и обдуваемых ветрами, дующих со склонов близлежащего Монблана. Но первое впечатление может быть обманчивым: водоёмы-близнецы являются центральными компонентами «Нан-де-Дранс», одной из самых оригинальных батарей в мире.

Такие проекты, известные как гидроаккумулирующие электростанции, которые накапливают электроэнергию в виде потенциальной энергии воды, перекачивая её вверх, приобретают всё большее значение, поскольку страны начинают включать возобновляемые источники энергии в свои энергетические балансы. Возобновляемые источники энергии непостоянны — в изобилии только тогда, когда светит солнце и дует ветер — поэтому, чтобы полностью заменить ископаемые виды топлива, они должны быть в состоянии круглосуточно удовлетворять потребности в энергии и поддерживать хрупкий баланс энергосистемы между спросом и предложением.

Сила воды

Европейский Союз имеет одни из самых высоких амбиций в мире в отношении смягчения последствий изменения климата. Существует жёсткий график почти полного прекращения использования ископаемого топлива и достижения углеродной нейтральности. Это означает, что подавляющее большинство видов личной и экономической деятельности, требующих энергии, должны быть электрифицированы из ВИЭ. По данным Европейской ассоциации хранения энергии (EASE), к концу десятилетия ЕС потребуются мощностью 200 ГВт накопителей энергии, а к 2050 году — 600 ГВт.

Поскольку развитые страны заинтересованы в использовании энергии из ВИЭ, существует необходимость хранения этой энергии, которая производится с перерывами в зависимости от погодных условий и времени суток. В то время как плотные аккумуляторные блоки являются решением проблемы, этим устройствам хранения нужны редкие металлы, такие как никель, кобальт и литий, добыча которых не является экологически чистым.

Учёные во всем мире экспериментируют с другими методами хранения энергии, такими как использование двуокиси углерода или использование грузоподъёмности лифтов в небоскрёбах для быстрого рассеивания энергии при пиковых нагрузках. Хотя они в значительной степени всё ещё являются экспериментальными, использование «водяных батарей» является давно известным рабочим методом. Гидроаккумуляторы являются наиболее ёмким типом накопителей энергии, доступных в настоящее время. Гидроаккумуляторы особенно полезны для хранения избыточной энергии, вырабатываемой прерывистыми источниками энергии, такими как ветер, Солнце и атомная энергия. Энергия перекачивается в верхний бассейн в периоды перепроизводства, а затем может быть высвобождена для производства энергии в периоды высокого спроса.

Примерная схема гидроаккумуляторной станции

Гидроаккумулятор мощностью 900 МВт, которая обошлась Швейцарии в 2 миллиарда евро и строилась 14 лет, запущена в работу. Аккумулятор расположен на глубине 600 м под землёй в швейцарских Альпах. Электростанция, построенная компанией Nant de Drance, была введена в эксплуатацию 1 июля 2022 года.

Гидроаккумулятор состоит из двух больших бассейнов с водой, расположенных на разной высоте. Когда выработка электроэнергии высока, избыточная мощность используется для перемещения воды из нижнего бассейна в бассейн повыше, что аналогично зарядке обычной батареи. Когда потребление электроэнергии увеличивается, вода с более высокого уровня спускается и, направляясь в нижний бассейн, проходит через турбины, которые вырабатывают электроэнергию. Это экологическая батарея, которая использует одну и ту же воду снова и снова. Выход составляет более 80 %: на каждый киловатт-час электроэнергии, используемый для перекачки воды вверх по течению, 0,8 подаётся в сеть.

Швейцарская гидроаккумуляторная станция имеет ёмкость хранения 20 миллионов кВтч, что эквивалентно ёмкости батарей от 400 000 электромобилей, и предназначена для стабилизации энергосистемы в Швейцарии и других подключённых сетей в Европе. На станции установлены шесть турбин, которые могут генерировать 900 МВт электроэнергии. Эти турбины-насосы практически не имеют аналогов в мире по своим размерам и используемой технологии. Менее чем за 10 минут можно изменить направление вращения турбин и переключиться с производства электроэнергии на хранение. Такая гибкость является ключевой для быстрого реагирования на потребности электросети и адаптации производства/потребления электроэнергии. В противном случае есть риск обрушения сети и отключения электроэнергии, как это произошло в Техасе в начале 2021 года.

Континентальный выключатель

Батарея построена между водохранилищами Emosson и Vieux Emosson в Вале, кантоне в юго-западной части Швейцарии. Объём воды, проходящей через турбины Нан-де-Дранс, достигает 360 кубических метров в секунду, что примерно соответствует потоку Роны в Женеве летом. Верхний резервуар Vieux Emosson вмещает 25 миллионов кубических метров воды, что соответствует ёмкости хранения 20 миллионов кВтч.

1 — Vieux Emosson, 2 — водозабор, 3 — предохранительные клапаны, 4 — вертикальные затворы, 5 — напорные трубы, 6 — электростанция, 7 — трансформаторная, 8 — предохранительные клапаны, 9 — водозабор, 10 — Emosson

Около 22 миллионов евро было потрачено на 14 проектов, чтобы компенсировать воздействие завода на окружающую среду, в основном на воссоздание определённых биотопов на местном уровне, чтобы стимулировать повторное заселение территории перемещёнными животными и растениями.

В пик строительства на стройплощадке работало 650 рабочих, а реализовывать строительство объединились около 60 компаний. Расположенная в самом сердце горы пещера электростанции длиной 194 м, высотой 52 м и шириной 32 м потребовала выемки 1 700 000 кубических метров породы и бурения 17 км тоннелей и галерей. Плотина Vieux Emosson, расположенная на высоте 2200 м, была поднята на 21,5 м, чтобы удвоить ёмкость водохранилища. При заполнении водохранилище Vieux Emosson может обеспечить около 18 гигаватт-часов электроэнергии.

1 — мостовые краны, 2 — генератор переменного тока, 3 — главный впускной клапан, 4 — турбина, 5 — главный сферический клапан, 6 — дренажный канал, 7 — вентиляция, 8 — частотные преобразователи, 9 — инверторы, 10 — автоматические выключатели, 11 — система управления, 12 — охладители, 13 — выпускная труба

Чтобы доставить строительные материалы на площадку, инженерам пришлось сначала прорыть туннели через Альпы. После того, как эти туннели были построены, строительные материалы и сборные дома можно было перемещать в гору, и этот процесс занял 14 лет. После всей этой тяжелой работы батарея теперь работает и на пике своей мощности способна одновременно обеспечивать электроэнергией 900 000 домов.

Электростанция жизненно важна для обеспечения электроснабжения и стабильности сети, но она «слишком велика для Швейцарии». Это может сыграть роль в стабилизации сети на континентальном уровне. Географически Швейцария находится в центре Европы, и энергетические потоки проходят через всю страну. Например, если в Германии будет перепроизводство ветровой энергии, то в Швейцарии смогут использовать излишки электроэнергии для перекачки и хранения воды. Однако не следует переоценивать роль гидроаккумулятора, которая, прежде всего, напрямую зависит от пропускной способности существующих сетей.

Эта концепция не нова, и использовалась в Италии и Швейцарии ещё в 1890-х годах. США с 1930-х годах также используют этот метод. По состоянию на 2019 год мощность хранения гидроэнергии в мире составляла 158 ГВт. А к 2025 году Китай решил построить гидроаккумулятор на 270 ГВт. Это удовлетворит 23% пикового спроса в стране. Кроме того, для сравнения, это больше, чем совокупная мощность всех электростанций в Японии. Национальное управление энергетики Китая (NEA) оценило потенциал хранения гидроэнергии в стране на уровне колоссальных 680 ГВт.

Испанская компания Iberdrola внесла свой вклад, открыв свою гигабатарею Tâmega в Португалии. По заявлениям компании, это один из крупнейших гидроаккумулирующих проектов в Европе мощностью 1,16 ГВт за последние 25 лет. Tâmega Gigabattery планируется модернизировать до гибридной электростанции путем интеграции двух ветряных электростанций. Она расположена на севере страны между Порту и испанским городом Оренсе. Объект стоит 1,5 миллиарда евро, и он ещё не завершен. Строительство Tâmega Gigabattery началось в 2014 году. Система будет иметь общую ёмкость хранения 40 ГВтч, что эквивалентно потребностям в электроэнергии 11 миллионов жителей в течение 24 часов.

В мире насчитывается около 616 000 потенциальных площадок, где можно было бы построить гидронасосные станции замкнутого цикла с двумя резервуарами. Достаточно построить всего 1 % из них, чтобы решить все проблемы, связанные с хранением прерывистой энергии, говорят в Австралийском национальном университете, основывая свою оценку на чисто географических соображениях.

В будущем будет всё больше необходимо хранить огромные объёмы электроэнергии, поскольку возобновляемые источники постепенно заменяют ядерную и ископаемую энергию. Однако солнечная и ветровая энергия являются энергозависимыми источниками, которые не обязательно производят электроэнергию, когда это необходимо. Поэтому такие системы, как этот швейцарский гидроаккумулятор, так важны, чтобы иметь возможность хранить энергию и поддерживать стабильность сети.


ссылка на оригинал статьи https://habr.com/ru/company/timeweb/blog/679222/

Электронный циркуль Тима


Первая из двух статей, посвящённых сборке электронных инструментов на основе датчика Холла. В этой части разбирается простейшая модификация циркуля, включающего в себя один датчик и два магнита. Вторая же часть будет посвящена более сложному инструменту — пантографу (прим. пер.).

Недавно мне пришла в голову идея собрать небольшой инструмент – электронный циркуль – чтобы показать базовые принципы работы датчика эффекта Холла. И в процессе съёмки ролика, демонстрирующего циркуль в действии, я решил также пояснить, как нахожу полюса используемых в этом циркуле магнитов.

Печать всех необходимых деталей я делал на 3D-принтере. В принципе, можно взять и другие материалы, но тут очень важна точность.

Основой проекта выступает датчик Холла 49Е и два магнита. Вычислениями при этом занимается Arduino Nano.

А поскольку AtMega328p оснащён всего лишь 10-битным АЦП, и в вычислениях используется синус, то придётся допустить некоторые погрешности. Результаты я буду выводить на двухстрочный дисплей 1602 с 16 символами на строку.

Если всё пойдёт хорошо, то я планирую реализовать и другие подобные проекты на датчиках Холла, а именно 2D и 3D-инструменты.

▍ Материалы

  • линейный датчик Холла 49E;
  • два неодимовых магнита, ширина 5мм, высота 2мм (Север/Юг определяется по оси высоты);
  • инструмент для определения полюсов магнитов. Я использовал приложение на телефоне;
  • Arduino Nano;
  • дисплей 1602 с интерфейсом I2C. (модуль PCF8575);
  • кабель;
  • клей, я взял УФ-смолу;
  • 3D-принтер для печати ножек циркуля.

Фото компонентов

Ссылки на STL-файлы для печати:

▍ Шаг 1: датчик Холла 49E

Датчики Холла выпускают многие компании, хотя большой разницы между ними нет. Ниже я приложил спецификацию, которую нашёл на Honeywell.

Лично я использовал самый дешёвый, какой смог найти в интернете, модель 49E, и пластиковые детали подогнал конкретно под него.

У этого датчика всего три вывода:

  • пин 1 = питание (от +2.7 до +6.5В).
  • пин 2 = земля (GND).
  • пин 3 = аналоговый вывод (обычно на 1 вольт меньше входного напряжения)

Вывод линейный, мВ/Гс.

В спецификации указано направление, в котором датчик определяет силу магнитного поля [N S]. Если двигать магнит ближе-дальше от датчика, то показания будут отражать магнитную силу в указанном направлении.

▍ Шаг 2: магниты

Для изменения силы магнитного поля вокруг датчика я использую два неодимовых магнита. Направление Север/Юг соответствует верху/низу магнитов, то есть ориентировано по оси высоты.

Разберём, как создаётся поле одним магнитом.

Поле сконцентрировано в его центре, где магнитные линии идут с Юга на Север параллельно. Выходя за края магнита, эти линии изгибаются и в итоге замыкаются с другой стороны — на противоположный полюс.

Если приблизить датчик к любому полюсу и сдвинуть его к одной из сторон, магнитная сила существенно снизится, поскольку линии магнитного поля замкнуты.

Датчики Холла очень чувствительны, поэтому их неточное расположение приведёт к ошибочным показаниям. Нам же нужно сократить возможное количество потенциальных ошибок. Жаль, нельзя разместить датчик внутри самого магнита — было бы идеально. Я же с целью уменьшить вероятность ошибок решил использовать два магнита.

Если расположить эти магниты недалеко друг от друга, то между ними возникнет однородное поле, близкое к такому, что должно быть внутри магнита. И если расположить в этой области датчик, то при повороте магнитов вокруг него поле должно сохранять тот же угол наклона, что и магниты.

▍ Шаг 3: вычисление угла

Магниты мы будем вращать вокруг датчика.

Вращение и простое отдаление магнитов от датчика – разные вещи. То есть в результате вращения на выводе мы будем получать не линейный результат, а значение синуса угла, на который происходит поворот.

Для лучшего понимания я сделал чертёж.

  • Фиолетовый кружок – это путь, по которому магниты движутся вокруг центра, то есть датчика.
  • синие линии представляют углы/позиции магнитов по мере их вращения.
  • жёлтыми линиями обозначена линейные силы, которые датчик будет регистрировать с Юга на Север.
  • зелёной линией показан график вычисления синусов.
  • красная – это зона точности.

Поскольку вывод датчика у нас аналоговый, выходит, что точность ограничена количеством десятичных знаков значения, в которое мы можем эти аналоговые показания конвертировать.

В Arduino Nano используется 10-битный АЦП. У этого микроконтроллера тип double аналогичен float, который имеет всего 6-7 десятичных знаков. И поскольку у нас происходит вращение, а не удаление магнитов от датчика, выводом будет результат вычисления синуса.

При этом в нашем случае также неизбежны участки, в которых 10-битный АЦП не позволит произвести точные расчёты.

Углы, которые можно вычислить точно, показаны синими линиями с кружочками на конце. Проблемные же углы обозначены линиями с крестиками.

По синусоиде видно, что в крайних положениях вращения в изменении магнитной силы делений градуса получается больше. Для лучшей наглядности я специально указал область точности.

Для охвата этих проблемных зон можно задействовать второй датчик, расположив его под 90° относительно первого. Это позволит использовать только точные области каждого.

В плане математики здесь простая тригонометрия, и я покажу это, когда дело дойдёт до кода.

▍ Шаг 4: сборка циркуля

Я уже сказал, что датчик очень чувствительный, и размещать компоненты необходимо очень чётко. В этом смысле мне помог 3D-принтер, который гарантирует точную печать деталей.

При установке минимальная погрешность в выравнивании допустима, но после фиксации гулять элементы уже не должны. Дополнительно некоторые огрехи в их расположении можно будет компенсировать в коде.

▍ Шаг 5: установка датчика

Датчик нужно вклеить в отведённую для него ножку циркуля (Sensor Arm). В этой детали есть специальное отверстие для определения его правильного положения.

▍ Шаг 6: Ориентация магнитов

Очень важно правильно выставить магниты. Я для этой процедуры использовал приложение на телефоне. Подойдёт такое решение только для устройств с магнитометром. Хотя обычно, если у телефона есть GPS, то и магнитометр тоже должен быть.

Что касается приложения, то из множества вариантов я предпочёл трёхмерный, а именно 3D Compass and Magnetometer. На изображении показано типичное 3D-приложение, в котором стрелка указывает в направлении севера.

Магнитометры в телефонах не всегда расположены по центру. Лучше всего выяснить его точное положение с помощью магнита, так будет проще разобраться с полюсами.

Зная расположение магнитометра, я обычно располагаю телефон в подвешенном положении над столом и кладу под него магнит, чтобы он оказался ровно под магнитометром, и уже тогда определяю полюса.

▍ Шаг 7: установка магнитов во вторую ножку циркуля

Здесь придётся немного повозиться.


Прежде чем соединять ножки, убедитесь, что магниты могут перемещаться внутри канавки той, что с датчиком — ходить они в ней должны плотно.

Магниты необходимо зафиксировать в одном положении, обеспечив правильную направленность их полюсов, и наложить внешнюю сторону второй ножки поверх первой.

После соединения подвижными должны быть только сами ножки, сдвигаясь и раздвигаясь, как это и положено циркулю. Никаких других побочных движений или люфтов быть не должно, иначе возникнут ошибки.

▍ Шаг 8: подключение кабеля

Следующим этапом нужно припаять к датчику провода для подключения Arduino.
Мой Arduino установлен на макетной плате, и для соединения с ним я на конце провода использовал разъём DuPont «мама».


Уточнить правильность соединения контактов можно в шаге 1.

▍ Шаг 9: ЖК-дисплей

Для отображения показаний датчика я использую двухстрочный ЖК-дисплей с 16 символами на строку. Кроме того, я использовал переходной модуль PCF8575, так что для подключения мне нужны только выводы I2C. К Arduino же я подцепил всё это 4-жильным кабелем с разъёмами типа «мама» (правильно ли я всё понял и выразил?…).

▍ Шаг 10: подключение к Arduino

Схема подключения к Arduino Nano в программе Fritzing:

Файлы для скачивания:

▍ Шаг 11: код

Если вы уже работали с Arduino Nano, то наверняка также посещали профильный ресурс Arduino.cc для изучения различных нюансов.

Для тех же, кто использует устройство с архитектурой Arduino впервые, я сначала рекомендую почитать раздел руководства: Arduino IDE 2 Tutorials

Здесь можно скачать Arduino IDE и изучить инструкции, написанные самими создателями этой платформы. Помимо прочего, тут же описывается, как загружать скетч на устройство.

Ниже приведён код, который можно скачать в приложенном файле Tims_Electronic_Deviders.ino.

После скачивания скетча нужно будет поместить его в каталог с тем же именем, но без .ino.

Код

/*     Tims_Electronic_Deviders.ino     By Tim Jackson.1960      Creadits:         Arduino.         LiquidCrystal_I2C based on work by DFRobot.      This is code for: Tim's Electronic Deviders.     I am using 3D Printed Deviders with a 49E Linear Hall Effect Sensor and two Magnets.     I am using an Arduino NANO to calculate the postion of the deviders from the values recived from the 49E Linear Hall Effect Sensor.     The sensor is linear: 3 mV/GS, but to get the angle a Sine of the value is calculated.      S=O/H C=A/H T=O/A     Degrees to Radians = degrees * (PI / 180)     Radians to Degrees = radians * 180.0 / pi  */ #include <Wire.h> #include <LiquidCrystal_I2C.h>  #define Hall_49R_Pin                    A1        //    Определение вывода датчика Холла #define CAL_0                            377        //    Показания датчика, когда угол равен 0 #define CAL_180                            690        //    Показания датчика, когда угол равен 180 #define CAL_RANGE (CAL_180 - CAL_0)                //    Максимальная величина CAL - минимальная величина CAL #define CAL_RAD ((double)CAL_RANGE / 2)            //    Используется в значении синуса H для получения угла. #define LEG_LENGTH 99                            //    Длина ножек циркуля. #define MAG_BIOS                        -3.11    //    Установить  на нуль, а затем изменить на значение, которое будет корректировать показания в районе 60 градусов. double Angle = 0;                                //    Переменная для значения Angle. double Length = 0;                                //    Переменная для значения Length. int SensorValue = CAL_0 + 1;                    //    Переменная для значения Sensor.  LiquidCrystal_I2C lcd(0x27, 16, 2);        //20 to    27    //    Установка адреса 2-строчного ЖК-дисплея на 0x27.   void setup() {     Serial.begin(115200);            //    Запуск Serial.     pinMode(Hall_49R_Pin, INPUT);    //    Определение датчика в качестве Input.      lcd.init();                        //    Запуск дисплея.     lcd.backlight();                //    Включение подсветки.     lcd.setCursor(0, 0);            //    Установка курсора на начало строки 0 (верхняя строка).     lcd.print(" Angle:");            //    Отображение метки Angle на верхней строке.     lcd.setCursor(0, 1);            //    Установка курсора на начало строки 1 (нижняя строка).     lcd.print("Length:");            //    Отображение метки Length на нижней строке.  } void loop() {      SensorValue = analogRead(Hall_49R_Pin);    //    Считывание значения с датчика.      Serial.println(SensorValue);            //    Отправка значения на Serial.     CalcAngle();                            //    Вычисление угла.     CalcLength();                            //    Вычисление длины.     Serial.println();                        //    Отправка символа новой строки на Serial для разделения значений.      delay(200);                                //    Ожидание выполнения. } /*     Вычисление Angle на основе значения, полученного от датчика.          S=O/H         Radians to Degrees = radians * 180.0 / pi          O = SensorValue - CAL_0 - CAL_RAD         H = CAL_RAD         Angle in radians = asin(O / H)         Angle in degrees = Angle in radians * 180.0 / pi;  */ void CalcAngle() {      double O = (double)SensorValue - CAL_0 - CAL_RAD;     double H = (double)O / CAL_RAD;     Angle = 90.0 + (asin(H) * 180.0 / PI);      Serial.print("Angle ");     Serial.println(Angle + MAG_BIOS, 4);      lcd.setCursor(7, 0);     lcd.print("  ");     lcd.setCursor(Xpos(Angle + MAG_BIOS), 0);     lcd.print(Angle + MAG_BIOS, 3);     lcd.print("  ");  } /*     Вычисление Length на основе градусов, вычисленных датчиком.          C=A/H         A=C*H         Degrees to Radians = degrees * (PI / 180)          C = (180 - Angle in degrees) / 2         H = LEG_LENGTH         A = C * H         Length = A * 2  */ void CalcLength() {      double _angle = (180.0 - Angle) / 2;     double _rad = _angle * (PI / 180);     double C = cos(_rad);     double H = LEG_LENGTH;     Length = C * H * 2;      Serial.print("Length ");     Serial.println(Length + MAG_BIOS, 4);      lcd.setCursor(7, 1);     lcd.print("  ");     lcd.setCursor(Xpos(Length + MAG_BIOS), 1);     lcd.print(Length + MAG_BIOS, 3);     lcd.print("  ");  } /*     Функция для вычисления положения значения, отображаемого на дисплее.          Проверить, указано ли значение в сотнях, десятках или единицах, чтобы соблюсти выравнивание чисел. . */ byte Xpos(byte number) {     byte val = 8;     if (number < 100) { val = 9; }     if (number < 10) { val = 10; }     return val; }

▍ Шаг 12: калибровка

Перед калибровкой значение #defined для MAG-BIOS необходимо установить на 0.

#define MAG_BIOS                        -3.11    //    Установить на 0, а затем изменить на значение, корректирующее показания в районе 60 градусов.

Для калибровки циркуля должен быть запущен Serial Monitor.

Закройте циркуль и запишите первое число, которое указано над Angle.

Откройте циркуль и снова запишите первое число, указанное над Angle. (я для соблюдения точных 180° произвожу эти манипуляции, положив циркуль на рабочий стол с разметкой).

Число при раскрытом циркуле, должно быть больше того, что отображалось при закрытом. Если получается наоборот — значит полярность магнитов перепутана.

Измените значения #defined для CAL_0 и CAL_180 согласно зафиксированным показаниям.

#define CAL_0                            377        //    Показания датчика, когда угол равен 0 #define CAL_180                            690        //    Показания датчика, когда угол равен 180

Ориентируясь на транспортир, выставьте циркуль в положение 60° и запишите отображённую величину угла. Пока циркуль находится в таком положении, с помощью линейки измерьте расстояние между его концами и запишите значение. Ошибка в градусах угла и расстоянии в миллиметрах будет одинаковой.

Измените значение #defined, чтобы компенсировать эту ошибку.

#define MAG_BIOS                        0    //    Установить на нуль, а затем на значение, корректирующее показания в районе 60 градусов

После калибровки показания будут близки к точным, кроме крайних значений от 0 до 15° и от 165 до 180°.

Дело в том, что в этих областях кривая синусоиды изменяется слабо.

▍ Шаг 13: повышение точности

Выше я продемонстрировал создание простейшего измерительного инструмента и принцип действия датчика Холла.

Модель 49E – это всего лишь один линейный аналоговый датчик, но здесь можно использовать и другие:

  • Модель AS5600 представляет собой легко программируемый 12-битный магнитный поворотный датчик положения с аналоговым или PWM-выводом, оснащённый интерфейсом I2C.
  • Модель MLX90393 предлагает 16-битный вывод, пропорциональный плотности магнитного потока, регистрируемой вдоль осей X, Y и Z. Можно выбирать между протоколами SPI и I2C.

Более дорогостоящие датчики обеспечат ещё большую точность.


ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/679476/

Дюк, вынеси мусор! — Часть 4

Зачем еще один?

Мы уже успели рассмотреть четыре различных сборщика мусора, разработанных для разных целей, разных профилей нагрузки, разного железа. Что же такого особенного хотели предложить разработчики ZGC, чего мы еще не встречали?

Официальное описание говорит нам о том, что при его проектировании ставились следующие цели:

  1. Поддерживать паузы STW на уровне меньше одной миллисекунды.

  2. Сделать так, чтобы паузы не увеличивались с ростом размера кучи, количества живых объектов или количества корневых ссылок.

  3. Поддерживать кучи размером до 16 ТБ.

Что ж, задачи амбициозные, думаю многим пригодится сборщик с такими характеристиками. Будем разбираться с тем, какие подходы использовались для решения этих задач.

Использование ZGC включается опцией -XX:UseZGC (в версиях JDK с 11-й по 13-ю она доступна только при использовании опции -XX:+UnlockExperimentalVMOptions).

Виртуальная память

Перед тем как начать разбираться с деталями работы ZGC, необходимо прежде всего освежить наши знания о принципах виртуализации памяти.

Виртуальная память поддерживает у каждого процесса иллюзию того, что он работает с большим и непрерывным адресным пространством, которое принадлежит лично ему. При этом на физическом уровне это пространство может быть не таким уж большим, совсем не непрерывным и не эксклюзивно выделенным только одному конкретному процессу.

В контексте рассмотрения работы ZGC нас будет прежде всего интересовать тот факт, что разные страницы виртуальной памяти могут указывать на одну и ту же страницу физической памяти. При этом создание таких страниц-двойников в виртуальном адресном пространстве не приводит к увеличению потребления памяти на физическом уровне.

Это, в частности, значит, что один и тот же объект в физической памяти может иметь несколько разных виртуальных адресов.

Далее мы увидим, как ZGC активно эксплуатирует эту особенность. Но предварительно нужно разобраться с устройством указателей на объекты при использовании данного сборщика.

Цветные указатели

Для достижения своих целей ZGC использует подход, называемый раскрашиванием указателей. На практике это означает, что каждый 64-битный указатель (а ZGC поддерживает только 64-битные системы) содержит не только адрес памяти, но и дополнительные метаданные, определяющие текущий статус указателя.

Под адрес в указателе выделяется от 42 до 44 младших бит в зависимости от установленного максимального размера кучи. Это значит, что ZGC может работать с кучами размером до 16 ТБ (одну из трех поставленных задач уже решили, это было несложно). До версии JDK 13 был вариант только с 42-битными адресами и ограничением на размер кучи 4 ТБ. Мы в данной статье будем рассматривать вариант с 44-битным указателем.

Еще четыре бита выделено под метаданные:

  • Marked0 (0001) и Marked1 (0010) — используются для пометки указателей на разных фазах сборки.

  • Remapped (0100) — указатель помечается этим битом в случае, если адрес в указателе является окончательным и не должен модифицироваться в рамках текущего цикла сборки.

  • Finalizable (1000) — этим битом помечаются объекты, достижимые только из финализатора.

Комбинация этих флагов определяет состояние указателя, которое при описании ZGC называется его «цветом».

А что с остальными 16-ю битами? Они всегда равны нулю и не используются.

В итоге, указатель на объект в памяти JVM при использовании ZGC имеет такую структуру:

Структура "цветного" указателя
Структура «цветного» указателя

Теперь давайте объединим это знание с тем, что мы вспомнили про устройство виртуальной памяти. В этом случае нулевой адрес (младшие 44 бита) с тем или иным установленным «красочным» битом будет представлять собой начало 16-терабайтной области в виртуальной памяти. Причем все эти области проецируются на одну и ту же область физической памяти — на кучу JVM:

Отображение виртуальной памяти на кучу
Отображение виртуальной памяти на кучу

Это значит, что устанавливая или снимая какой-либо из битов метаданных указателя (перекрашивая указатель), не меняя адреса, мы переносимся в другую область виртуальной памяти, но при этом получаем виртуальный указатель на тот же самый объект, на который ссылались до перекрашивания. Удобно.

Барьеры

Еще одной особенностью ZGC является использование т. н. барьеров (barriers) во время конкурентных фаз сборки мусора (когда сборщик работает одновременно с приложением, не останавливая его выполнение).

Барьер — это просто функция, которая принимает указатель на объект в памяти, анализирует цвет этого указателя, в зависимости от цвета выполняет какие-либо действия с этим указателем или даже с самим объектом, на который он ссылается, после чего возвращает актуальное значение указателя, которое необходимо использовать для доступа к объекту.

Важной особенностью функции-барьера является то, что она выполняется в том числе в рамках основных потоков приложения. То есть сборкой мусора занимаются не только выделенные потоки GC, но и само приложение, чего мы в предыдущих сборщиках не встречали.

Какие конкретно манипуляции барьеры производят с указателями и с объектами, мы рассмотрим ниже. Пока что нам достаточно знаний просто про наличие таких барьеров.

Поиск живых объектов

Теперь давайте посмотрим, как ZGC использует цветные указатели и барьеры для очистки кучи. Первым этапом работы сборщика является покраска указателей на достижимые объекты.

Для иллюстрации работы ZGC будем использовать пример из презентации Oracle. Начинается всё с такого расположения и состояния объектов:

Начальное состояние кучи
Начальное состояние кучи

Дальше в описании мы будем раскрашивать указатели разными цветами в соответствии с состоянием их метаданных. Для наглядности объекты тоже будем раскрашивать.

Этап поиска живых объектов и первоначальной раскраски ссылок состоит из трех фаз:

Фаза Pause Mark Start

Сборка мусора, как обычно, начинается с поиска живых объектов. А поиск живых объектов, как обычно, начинается с поиска объектов, достижимых из корней. Для этого ZGC использует короткую STW-паузу. Если вы не понимаете что-то в этих трех предложениях, лучше еще раз перечитать как минимум первую статью данного цикла

Особенностью ZGC является то, что в процессе обхода кучи он не только определяет, какие из объектов являются живыми, но и попутно красит указатели, по которым путешествует, устанавливая у них один из битов Marked0 или Marked1.

На этом этапе выберем красный цвет для раскрашивания ссылок, по которым мы добирались до живых объектов. В результате получаем такую картину:

После пометки корней
После пометки корней

Фаза Concurrent Map

После того, как найдены все объекты, достижимые из корней, работа приложения возобновляется и начинается вторая фаза сборки, в которой сборщик продолжает поиск живых объектов, достижимых из найденных корней, но уже в конкурентном режиме.

Так как во время этой фазы приложение работает и может создавать новые объекты, в этот период активно используются барьеры, которые красят все указатели, по которым в это время производится доступ к объектам.

Фаза Pause Mark End

После завершения конкурентной фазы опять возникает пауза STW, в рамках которой ZGC обрабатывает различные специальные кейсы. В частности, soft- и weak-references.

В результате все указатели на живые объекты оказываются раскрашенными, а все объекты, до которых можно добраться по таким указателям, являются достижимыми:

После пометки всех живых объектов
После пометки всех живых объектов

Перемещение

Следующий этап в работе ZGC — это перемещение объектов для дефрагментации и высвобождения памяти. Данный этап так же разбит на несколько фаз:

Фаза Concurrent Prepare for Relocate

В рамках этой активности сборщик определяет блоки памяти, объекты из которых подлежат перемещению. Эти блоки попадают в так называемый набор для перемещения (relocation set).

В такой набор заносятся блоки, в которых находится достаточно много мертвых объектов, чтобы их перемещение приносило пользу:

Выбраны блоки для перемещения
Выбраны блоки для перемещения

Фаза Pause Relocate Start

Дальше начинается непосредственно перемещение объектов. Как и их поиск, перемещение начинается с объектов, достижимых из корней, и производится в рамках паузы STW.

Если объект достижим по указателю из корня и подлежит перемещению, он переносится в новый блок памяти, корневой указатель на него красится и сборщик запоминает соответствие старого и нового адреса перемещенного объекта в специальных таблицах переадресации (forwarding tables). Такие таблицы ведутся отдельно для каждого блока в памяти за пределами кучи.

Корневые указатели на объекты, не подлежащие перемещению, просто перекрашиваются в тот же цвет.

После перемещения корневых объектов
После перемещения корневых объектов

Фаза Concurrent Relocate

Эта фаза распространяет описанную выше активность переноса объектов (вместе с ведением таблицы переходов) на оставшуюся кучу.

Как следует из названия, происходит она в конкурентном режиме, одновременно с работой приложения. А это значит, что в рамках нее активно используются барьеры. Но эти барьеры выполняют уже не только раскраску указателей, но и физическое перемещение объектов если они обнаружили доступ по указателю к объекту, подлежащему перемещению, но еще не перемещенному.

Например, без работы барьеров картина после данной фазы выглядела бы вот так:

Объекты перенесены, но указатели не перекрашены
Объекты перенесены, но указатели не перекрашены

Но если в течение этой фазы приложение попыталось получить объект 5 по устаревшему указателю из объекта 4, то барьер корректно перенаправит и перекрасит этот указатель:

Указатель перекрашен барьером
Указатель перекрашен барьером

Фаза Concurrent Remap

После окончания предыдущей фазы все объекты оказываются перемещенными в целевые области памяти и единственное, что отделяет нас от окончательной целевой картины, это зависшие указатели на объекты в освобожденных регионах памяти (они остались красными на схеме).

Чтобы поправить все такие указатели, необходимо совершить еще один обход графа объектов, проследовав по всем указателям и перенаправив их на новые адреса в соответствии с таблицами переадресации. Но ZGC не выполняет эту фазу сразу в рамках текущего цикла сборки, а совмещает ее с фазой Concurrent Mark следующего цикла сборки. То есть фазы в разных циклах сборки накладываются друг на друга:

Организация фаз внутри циклов сборки
Организация фаз внутри циклов сборки

После фазы Pause Mark Start следующего цикла сборки будут помечены объекты, достижимые из корней:

После пометки корней в следующем цикле сборки
После пометки корней в следующем цикле сборки

И далее в рамках фазы Concurrent Mark коллектор пройдется по всем оставшимся указателям, обнаружит несоответствие их цветов (красные) текущей фазе сборки (синий) и поправит. Либо сама программа, получая объекты по таким зависшим указателям и вызывая срабатывание барьеров, будет перемещать объекты и перекрашивать указатели в актуальный цвет.

В результате после завершения этой фазы всё встанет на свои места:

Результат сборки мусора
Результат сборки мусора

Полная сборка

Описанный алгоритм позволяет выполнять большую часть работы по сборке мусора не останавливая работу основных потоков приложения. Но он, конечно же, не гарантирует, что у приложения в любой момент есть достаточно свободной памяти.

При активном выделении памяти может возникнуть ситуация, когда у JVM не осталось свободных блоков для размещения новых объектов. В этом случае работа приложения останавливается (пауза STW) и, как и при использовании других сборщиков, запускается цикл полной сборки мусора. Здесь, конечно, речь о субмиллисекундных паузах уже не идет.

Настройка

ZGC можно настраивать с помощью нескольких опций, позволяющих регулировать интенсивность его работы, что на практике значит разменивать ресурсы процессора и оперативную память на скорость очистки кучи.

С помощью опции -XX:ZFragmentationLimit=percent можно задавать процент фрагментации, при достижении которого блок памяти попадает в набор для перемещения. Чем меньше значение, тем интенсивнее очистка памяти.

Используя опцию -XX:ZCollectionInterval=seconds можно установить максимальное время между сборками, то есть инициировать сборку в некоторых случаях, когда сам сборщик пока еще не считает это необходимым.

Опция -XX:ZAllocationSpikeTolerance=factor определяет, насколько большие всплески активности по выделению новой памяти ожидает сборщик. На основании таких ожиданий ZGC планирует последующие сборки, чтобы в штатном режиме успевать собирать мусор до того, как иссякнет резерв свободных блоков и придется проводить полную сборку.

С помощью опции -XX:+ZProactive можно включать или выключать проактивный режим, в котором ZGC может инициировать сборки мусора в случаях, когда явной необходимости в этом нет, но ожидаемое влияние на работу основных потоков приложения минимально.

Опции -XX:ZUncommit и -XX:ZUncommitDelay регулируют возврат неиспользуемой памяти операционной системе.

Ну и общая для многопоточных сборщиков опция -XX:ConcGCThreads=threads (ровно как и другие общие опции), позволяющая задавать количество выделенных на сборку мусора потоков, применима и в ZGC.

Достоинства и недостатки

На практике ZGC, действительно, позволяет добиться субмиллисекундных пауз, в том числе на очень больших кучах, что очень хорошо для приложений, чувствительных даже к коротким задержкам в обработке запросов.

Паузы, действительно, короткие
Паузы, действительно, короткие

Но эти короткие паузы не даются бесплатно.

Во-первых, из-за наличия длительных конкурентных фаз сборки может страдать пропускная способность приложения. Насколько сильно — зависит от конкретного приложения.

Во-вторых, используемые для доступа к объектам барьеры совсем не бесплатные. В разных источниках фигурируют оценки замедления перехода по указателю на 4-5%, но это в оптимистичном сценарии, когда цвет указателя «хороший» и барьеру не требуется менять сам указатель или переносить соответствующий объект на новое место. В случае обнаружения «нехорошего» цвета указателя барьеру придется уйти на длинный путь и потратить значительно больше времени на приведение данных в порядок.

В-третьих, чтобы держать паузы на субмиллисекундном уровне и не допускать полных сборок мусора ZGC требуется достаточное количество свободных регионов памяти. Если ваше приложение очень активно создает новые объекты, ему, скорее всего, потребуется куча чуть большего размера, чем при использовании того же G1.

Заключение

Мы начали разбор ZGC с декларируемых целей его разработки. Достигнуты ли эти цели?

В целом, похоже, что да, но, естественно, с оговорками, что вы выделите приложению достаточное количество ресурсов и не будете сами себе откровенно вредить, непомерно мусоря, создавая очень большое количество корневых объектов, используя финализаторы и другие недружелюбные к GC практики.

Иметь такой сборщик в арсенале JDK очень приятно и наверняка есть немало приложений, для которых он окажется оптимальным выбором.

Использовать или не использовать конкретно вам? Как всегда, единственный разумный универсальный ответ на этот вопрос — анализируйте требования к своему приложению, тестируйте на своих нагрузках, аккуратно разбирайтесь с причинами в случае не устраивающих вас результатов, делайте выводы.

Ранее:

← Часть 3 — Сборщики CMS и G1

← Часть 2 — Сборщики Serial GC и Parallel GC

← Часть 1 — Введение


ссылка на оригинал статьи https://habr.com/ru/post/680038/