Як багато з вас знали, що Java колись мала назву Oak?
Як же це символічно бачити Гослінга і те, що його слова вступні!
Всім привіт, сподіваюся що всі хто долучиться до трансляції проживуть ці моменти розвитку Java разом зі мною. Для мене це стало частиною роботи і життя, тому ця документалка для мене це щось дуже особисте. Сподіваюся і для Вас. Приємного перегляду!
Писати — можна і лише якщо рез корпоративні ресурси. Очікувати відповіді — ні в якому разі (окрім як оговорених овертаймів).
Писати — можна. Очікувати відповіді — ні.
Виділіть достатньо пам’яті (-Xmx) і визначте прийнятні межі пауз (-XX:MaxGCPauseMillis) або частки часу (-XX:GCTimeRatio) — ці параметри задають стратегічну ціль для збирача.
це теж необовʼязково робити, наприклад, в контейнірізованих системах рантайм все зробить за вас.
Якщо мова йде про новітні і надпотужні GC типу ZGC — то там взагалі не треба нічо робити, а ні памʼять, а ні межу части часу. До цього ж все йде. Це раніше треба було розумітися на параметрам JVM щоб робити тюнінг, і були окремі люди як це вміли робити по живому в продакшенах. Зараз люлям краше розумітися на JMH і профайлінгу власного коду, а ніж лізти всередину без фундаментальних знань.
дивлячись де студенти вчаться, я зараз працюю над порталом https://learn.java як раз із метою зробити так, щоб Java вивчали більше студентів. і моя команда працює із college board щоб універи та колледжи обирали першою мовою Java no matter what.
Ого, він був моїм керівником по магістрату в ХНУРЕ по профілю безпеки. Скажемо так, він досі суворий начальник, але без тупих перегибів як в совкових вояк.
А дайте посилання на сабреддіт, будь ласка.
Як людина як розробляє та використовує провайдери в великому ентеопрайзі я можу сказати, що русня рветься на японський прапор тупо задарма. Лише показують які вони кволі. Ми давно вже не використовуємо стандартний публічний регістрі та перейшли на власний, навіть provider for Oracle Cloud Integrated (OCI) давно вже лежить на корпоративних серверах.
Тому, «мені подобається як воно горить, усі суєтяться, бігають», а я на минаю попкорн і радію по-троху.
Причому тут стейт? Наш UDP сервер взагалі був stateless. Я ж кажу про застосунки, які дуже чутливі до stop the world пауз. У цьому ж незрівненна перевага generational zgc з його sub-millisecond паузами.
Поділюся цікавим досвідом чому саме треба обирати ZGC. Я працюю над проєктом де є високочастотні UDP клієнти які генерують приблизно по 35 мегабайт датаграм в секунду. Таких клієнтів за одну сесію може бути до 22 одночасно упродовж двох годин. Нажаль, G1 давав великі паузи за які втрачалися приблизно
Ще забули додати велику секцію про керування off-heap або native памʼяттю. Project Panama додала такий функціонал в JDK22 через арени які привʼязані до стеку та контролюються GC.
Відносно GC. ZGC це вже де-факто стандарт для рантайму в незалежності від розмірів heap. Ну і ідея generational полягає в тому, що GC сам може себе ефективно налаштувати, тюнінг як такий йде у минуле.
Це все стає недоречним, якщо позбутися асинхронного коду і використовувати structured concurrency з Project Loom.
Обурення розумію, погоджуюсь, але дозвольте запитати. A JDK Stream::parallel не порушує цю концепцію? У нього ж теж, здається, ExecutorService назовні не стирчить?
Формально, ви праві. Але фактично є можливість обходити це обмеження, бо паралельні стріми «розуміють» із чим вони мають справу. Приклад я навів трохи нижче.
Я буду радий вам допомогти оформити JEP або тікет якщо буде відповідна мотиваційна частина.
Я теж таке пам’ятаю. Тому, здається, є рекомендація в parallel робити хіба що СPU операціі, тому що I/O може «вичерпати» той єдиний для всіх ForkJoinPool і це заафектить інші parallel стріми.
Так, все вірно. Мова йде про FJP який створюється підчас ініціалізації віртуальної машини, воно зветься Common FJP. Коли мова йде про паралельні потоки, завжди контекст задачі повинен крутитися навколо CPU (математика, вектори і так далі). У цей же час, для віртуальних потоків була створена паралельна інфраструктура — свій FJP (такий самий як і common) і свої підходи по паралельного програмування — structured concurrency.
Що стосується факту, що в паралельних стрімах неможливо вказати із яким ExecutorService працювати, то є простий підхід як вказати який сервіс використовувати:
var forkJoinPool = new ForkJoinPool(100); var primes = forkJoinPool.submit(() -> // Parallel task here, for example IntStream.range(1, 1000).parallel() .filter(PrimesPrint::isPrime) .boxed().collect(Collectors.toList()) ).get();
Тут, звісно, треба зауважити, що паралельний I/O — це дивна ідея
ну, дивного тут нічого нема, повірте, коли мова йде про паралельні стріми, то як ви відмітили це bulk-операції. Але для I/O більш притаманні задачі структурного паралелізму: задачі із «певною» кількістю I/O перемикань (context switch, blocking). Тому й існує StructuredConcurrency як спосіб виконання як bulk-задач, так і послідовних блокувань-очікувань у структурному, а не асинхронному вигляді.
З цим теж, звісно, згоден. Було б гарно зробити на рівні мови синтаксичний цукор для кожного isXXX() метода автоматичний isNotXXX, тому що в !longButSelfExplainableObjectName.isFineQualifiedBooleanMethod() знак оклику на початку, особливо біля «l», не видно. Тяжка спадщина assembler/C, 0 — це false, 1 — це true; добре, що хоч boolean завезли.
Я залюбки допоможу оформити JEP, або тікет на цей функціонал якщо є відповідна мотиваційна частина, а ніж небажання писати знак оклику перед методом =)
для мене дивно, що дизайн кожного фремворку робився так, щоб сховати найелементарнішу річ — ExecutorService. Це ж просто база, основа, стовп фреймворків що працюють із сокетами. Наприклад, Netty — одна з найгірших бібліотек і серверів загалом, бо йде суміш JNI та багатопотоковсті.
Для тих, хто не дуже розуміє мого палання стільця. Проблема полягає в тому, що загалом фремворки роблять вигляд що знають краще за розробників. Для мене очевидне краще, а ніж advanced-приховане. Є задачі під які можна створити cached-pool, а не створювати-видаляти потоки кожного разу як це потрібно, бо можна забути про будь-яку C2 оптимізацію. І таких моментів багато (це також стосуються усіляких імплементацій jdbc connection pool).
Фіналочка. Java-розробникик ВЖЕ НЕ КОРИСТУЮТЬСЯ мануальним створенням потоків, для цього є ExecutorService та Future. За пафосними ідеєю створбювати «високорівневі фремворки» ховається бридкий код який ховає базові речі JDK. Так робити не можна.
Іронічно, що вся команда Oak була звільнена, проте продовжила робити технологію.