Путь байтов в памяти JVM при сетевом взаимодействии
Сетевой ввод-вывод в Java проходит через сложную цепочку от сетевой карты до кучи JVM и обратно. Понимание этого пути критично для оптимизации производительности и управления памятью.
1. От сетевой карты до ядра ОС
Когда пакет приходит на сетевой интерфейс, NIC (Network Interface Controller — сетевой контроллер) генерирует аппаратное прерывание. Драйвер сетевой карты в ядре ОС обрабатывает прерывание, копирует пакет из буфера NIC в кольцевой буфер (ring buffer) ядра — структуру данных фиксированного размера в оперативной памяти, организованную по принципу FIFO (First In, First Out — первым пришёл, первым вышел). Затем стек TCP/IP ядра обрабатывает пакет: проверяет IP-заголовок, TCP-заголовок, вычисляет checksum, обновляет состояние соединения.
Данные приложения из TCP-сегментов накапливаются в сокет-буфере (socket receive buffer) ядра — области памяти ядра, выделенной для конкретного сокета. Размер этого буфера настраивается через опции сокета
2. Из ядра в JVM: read() и ByteBuffer
Когда Java-приложение вызывает
Здесь критично различие между двумя типами
3. Работа GC с сетевыми буферами
Объект
Однако Cleaner срабатывает только при сборке мусора. Если приложение активно выделяет
4. Путь отправки данных
При записи (
Данные из
Стек TCP ядра сегментирует данные, добавляет заголовки TCP/IP, вычисляет checksum.
Сегменты попадают в очередь передачи NIC и отправляются в сеть.
При получении ACK от получателя ядро освобождает соответствующие сегменты из send buffer.
Если send buffer заполнен (получатель не успевает читать), вызов
5. Объекты сетевого стека в JVM
При использовании NIO с Selector в куче JVM хранятся:
Объект
Объекты
Объекты
Эти объекты лёгкие и живут в Young Generation. При закрытии канала (
#Java #для_новичков #beginner #IO #NIO #Ip #Port #TCP #UDP
Сетевой ввод-вывод в Java проходит через сложную цепочку от сетевой карты до кучи JVM и обратно. Понимание этого пути критично для оптимизации производительности и управления памятью.
1. От сетевой карты до ядра ОС
Когда пакет приходит на сетевой интерфейс, NIC (Network Interface Controller — сетевой контроллер) генерирует аппаратное прерывание. Драйвер сетевой карты в ядре ОС обрабатывает прерывание, копирует пакет из буфера NIC в кольцевой буфер (ring buffer) ядра — структуру данных фиксированного размера в оперативной памяти, организованную по принципу FIFO (First In, First Out — первым пришёл, первым вышел). Затем стек TCP/IP ядра обрабатывает пакет: проверяет IP-заголовок, TCP-заголовок, вычисляет checksum, обновляет состояние соединения.
Данные приложения из TCP-сегментов накапливаются в сокет-буфере (socket receive buffer) ядра — области памяти ядра, выделенной для конкретного сокета. Размер этого буфера настраивается через опции сокета
SO_RCVBUF.2. Из ядра в JVM: read() и ByteBuffer
Когда Java-приложение вызывает
SocketChannel.read(buffer), происходит переход из пользовательского пространства в пространство ядра (system call). Данные копируются из сокет-буфера ядра в буфер JVM.Здесь критично различие между двумя типами
ByteBuffer:HeapByteBuffer — буфер, размещённый в куче JVM (Heap). При чтении из канала данные сначала копируются во временный буфер в нативной памяти (выделенный JNI), а затем — в массив byte[] в куче. Это двойное копирование снижает производительность.
DirectByteBuffer — буфер, размещённый в нативной памяти (native memory, вне кучи JVM). При чтении данные копируются напрямую из сокет-буфера ядра в нативную память, минуя кучу. Это устраняет одно копирование и позволяет использовать zero-copy техники на уровне ОС.
// HeapByteBuffer: данные в куче, медленнее при I/O
ByteBuffer heapBuffer = ByteBuffer.allocate(1024);
// DirectByteBuffer: данные в нативной памяти, быстрее при I/O
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
Zero-copy — это техника, при которой данные не копируются между буферами в пользовательском пространстве, а передаются по ссылке или напрямую из ядра в целевой буфер. В Java FileChannel.transferTo() и transferFrom() используют zero-copy для передачи данных между файлами и сокетами без промежуточного буфера в пользовательском пространстве.
3. Работа GC с сетевыми буферами
Объект
ByteBuffer в Java — это обёртка. Для HeapByteBuffer он содержит ссылку на byte[] в куче. Для DirectByteBuffer он содержит адрес в нативной памяти (поле address типа long). Сам объект DirectByteBuffer — маленький объект в куче (десятки байтов), но он ссылается на большой блок нативной памяти (мегабайты).Cleaner — это механизм в JVM, использующий PhantomReference (фантомную ссылку) для регистрации callback-функции, которая вызывается, когда объект становится пригодным для сборки мусора. Когда DirectByteBuffer собирается GC, Cleaner вызывает нативный метод free(), который освобождает блок нативной памяти через Unsafe.freeMemory().
PhantomReference — это тип ссылки в Java, который позволяет узнать, что объект был финализирован сборщиком мусора, но ещё не удалён. В отличие от WeakReference и SoftReference, phantom reference не даёт доступа к объекту, но гарантирует, что объект уже недостижим.
Однако Cleaner срабатывает только при сборке мусора. Если приложение активно выделяет
DirectByteBuffer, но GC не запускается (потому что куча не заполнена), нативная память может исчерпать лимит ОС, вызывая OutOfMemoryError: Direct buffer memory. Чтобы избежать этого, важно явно вызывать cleaner.clean() (через рефлексию) или использовать пулы буферов (например, Netty ByteBuf), которые переиспользуют выделенную память.4. Путь отправки данных
При записи (
SocketChannel.write(buffer)) путь обратный:Данные из
ByteBuffer (куча или нативная память) копируются в сокет-буфер отправки ядра (socket send buffer).Стек TCP ядра сегментирует данные, добавляет заголовки TCP/IP, вычисляет checksum.
Сегменты попадают в очередь передачи NIC и отправляются в сеть.
При получении ACK от получателя ядро освобождает соответствующие сегменты из send buffer.
Если send buffer заполнен (получатель не успевает читать), вызов
write() вернёт 0 записанных байт в неблокирующем режиме или заблокирует поток в блокирующем режиме.5. Объекты сетевого стека в JVM
При использовании NIO с Selector в куче JVM хранятся:
Объект
Selector — содержит ссылку на нативную структуру pollfd (Linux) или WSAPOLL (Windows).Объекты
SelectionKey — хранятся в HashSet внутри Selector, по одному на каждый зарегистрированный канал.Объекты
SocketChannel и ServerSocketChannel — обёртки над файловыми дескрипторами ОС.Эти объекты лёгкие и живут в Young Generation. При закрытии канала (
channel.close()) файловый дескриптор освобождается нативным кодом, а Java-объект становится мусором для следующей Minor GC. Однако если забыть закрыть канал, дескриптор утечёт на уровне ОС — это утечка файлового дескриптора (file descriptor leak), которая при масштабе приводит к исчерпанию лимита ulimit -n и невозможности открыть новые соединения.// Правильный паттерн: try-with-resources для автоматического закрытия
// Closeable — интерфейс, требующий реализации метода close()
try (SocketChannel channel = SocketChannel.open(new InetSocketAddress("host", 80))) {
ByteBuffer buffer = ByteBuffer.allocateDirect(4096);
channel.read(buffer);
} // channel.close() вызывается автоматически, освобождая файловый дескриптор
#Java #для_новичков #beginner #IO #NIO #Ip #Port #TCP #UDP
👍4
Что выведет код?
#Tasks
import java.net.InetAddress;
public class Task140826 {
public static void main(String[] args) throws Exception {
InetAddress addr = InetAddress.getByName("");
System.out.println(addr.getHostAddress());
}
}
#Tasks
👍2
👍2
Что такое 🤓
Ответ:
JPQL — это объектно-ориентированный язык запросов, похожий на SQL, но работающий с сущностями и их полями, а не с таблицами и колонками.
Пример: SELECT u FROM User u WHERE u.age > 18.
Поддерживает JOIN, GROUP BY, ORDER BY, агрегации. Отличается от нативного SQL тем, что не зависит от конкретной СУБД.
Поддерживает параметры: :name (named) или ?1 (positional). Используется с EntityManager.createQuery().
Для сложных запросов можно использовать Criteria API или нативные запросы (@NativeQuery ).
#собеседование
JPQL (Java Persistence Query Language)? Ответ:
JPQL — это объектно-ориентированный язык запросов, похожий на SQL, но работающий с сущностями и их полями, а не с таблицами и колонками.
Пример: SELECT u FROM User u WHERE u.age > 18.
Поддерживает JOIN, GROUP BY, ORDER BY, агрегации. Отличается от нативного SQL тем, что не зависит от конкретной СУБД.
Поддерживает параметры: :name (named) или ?1 (positional). Используется с EntityManager.createQuery().
Для сложных запросов можно использовать Criteria API или нативные запросы (
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
15 августа (дата отмечается как Computer Science Day) — день, посвящённый дате запуска первого массового электронного компьютера ENIAC.
Лесли Джон Комри (15 августа 1893 г. – 11 декабря 1950 г.) — Астроном и пионер механической/механографической автоматизации вычислений; один из ранних организаторов коммерческих вычислительных услуг и автоматизации таблиц — предтеча компьютерной обработки данных.
Пьер Буге́р (также Буге; фр. Pierre Bouguer; 16 февраля 1698, Круазик (Croisic), Франция — 15 августа 1758, Париж) — французский физик, математик и астроном, основатель фотометрии. Известен трудами по теории корабля, геодезии, гидрографии и другим отраслям знания. Имя Бугера внесено в список 72 величайших учёных Франции, размещённый на первом этаже Эйфелевой башни.
1877 — американский изобретатель Томас Эдисон в письме президенту телеграфной компании Питтсбурга предложил в качестве приветствия при общении по телефону использовать слово «hello» (в России оно трансформировалось в «алло»). В этот же день Эдисон произвёл первую запись звука на свой фонограф — песню «Mary Had a Little Lamb» («У Мэри был барашек»).
1977 — радиотелескоп Big Ear (Огайо, США) зафиксировал "Wow! signal" — один из самых известных возможно внеземных радиоимпульсов.
1998 — компания Apple начала поставки iMac G3, модели, которая кардинально изменила дизайн и восприятие компьютеров в массовом сознании.
#Biography #Birth_Date #Events #15Августа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Напоминаю, что продолжаю набирать желающих изучить Java!
Устройств на работу не обещаю, но до мидла (java/spring) доведу.
Пишите @Oleborn
Устройств на работу не обещаю, но до мидла (java/spring) доведу.
Пишите @Oleborn
🤓2
Христос Харилаос Пападимитриу (греч. Χρήστος Χαριλάος Παπαδημητρίου; род. 1949, Афины) — один из ведущих теоретиков в компьютерных науках; важные работы по теории алгоритмов, сложности вычислений и теория игр, автор фундаментальных учебников и исследований. Член Национальных Академии наук (2009) и Инженерной академии США, профессор Калифорнийского университета в Беркли.
1890 — Электромеханическая обработка переписи США: Бюро переписи объявляет результаты, подсчитанные машинами Германа Холлерита — рубеж для истории вычислений и табуляторов.
1993 — Иан Мёрдок основал сообщество «Debian», занимающееся созданием и распространением свободного дистрибутива Debian GNU/Linux.
2006 — в русской Википедии появилась юбилейная, 100-тысячная статья.
#Biography #Birth_Date #Events #16Августа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Софт-скиллы, которым не учат в курсах
Вот представь, ты прочитал весь мой канал, изучил синтаксис вдоль и поперек, научился виртуозно делать API, освоил Git, знаешь Spring и WebFlux.
Но вот пришло собеседование — и ты... завис.
— Расскажите о себе.
— Ну… я... типа… учился… кодить...
Знакомо?
А теперь еще предположим: ты уже устроился и тебе дали таску.
И ты видишь, что надо уточнить у тимлида детали.
Но в голове:
«А если я спрошу — подумает, что тупой...»
«Лучше погуглю еще 3 часа, чем покажусь нубом»
«Он ведь профи. Я даже не знаю с чего начать...»
Это называется - коммуникативная тревожность.
Она же — тихий киллер карьеры в IT.
Почему ты боишься говорить
Вот тебе правда: страх общения — это не про характер.
Это навык.
Даже самые «разговорчивые» разработчики когда-то:
- боялись скинуть Pull Request с комментариями,
- часами переписывали сообщение в телеграмме,
- репетировали простой вопрос голосом.
Почему некоторым в IT это так сложно?
Потому что IT часто привлекает интровертов, бывших «отличников», людей, которые учились всё понимать сами, без помощи. И теперь, оказавшись в команде — они просто не умеют задавать вопросы или входить в беседу.
Что происходит в голове?
В когнитивной психологии есть понятие self-presentation concern — это тревога из-за того, как тебя воспримут другие.
Именно она:
- заставляет молчать, когда нужно спросить;
- мешает делиться идеями;
- блокирует на стендапах.
А ещё есть спираль молчания — если ты боишься говорить, ты выпадаешь из общения, и из-за этого боишься ещё больше.
Вот пара моих советов если ты чувствуешь что твой софт-скилл слабоват:
Говори, даже если страшно.
Но не вживую, а письменно.
Заведи привычку активно писать: в рабочем чате, в Telegram, в комментариях к pull request'ам.
Так ты приучаешь мозг к выражению мысли — без страха, что тебя перебьют или осудят.
Это снижает тревожность, активирует рефлексивную речь — внутреннее проговаривание и структуру мысли.
Не бойся задавать глупые вопросы.
Как сказал один умный человек: "В IT нет глупых вопросов, есть чересчур ЧСВ-шные отвечающие"
Микроконтакт — это уже общение
Не нужно фигачить речь на 3 минуты.
Просто начни с одной фразы:
«А почему мы сделали вот так, а не так?»
«Спасибо, крутая реализация»
«Подскажи, я что-то путаюсь в этой части»
Это называется anchored small talk — микровзаимодействия, которые создают эффект «я в теме». Даже если ты мало говоришь.
Заготовь фразы. Да, можно и записать
Серьёзно.
Напиши себе в заметках:
Вопрос на стендап: «Ребят, я правильно понимаю, что…»
Начало диалога: «Можно короткий вопрос про фичу?»
Завершение: «Окей, тогда попробую и отпишусь»
В момент тревоги мозг не придумывает речь с нуля. Он вытаскивает готовое.
Подсунь ему нужные заготовки — и увидишь, как снижается стресс.
Найди «одного своего»
Не команду. Не менторов. Одного союзника, с кем безопасно говорить.
Пишете вместе код — обменивайтесь мыслями.
Работаете на проекте — обсуждай идеи.
В сообществе — шутите, делитесь опытом.
Это снижает страх перед всей группой. Есть ощущение, что ты не один. А с этого и начинается уверенное взаимодействие.
Ты можешь спросить: "А зачем мне это вообще?"
Пойми:
Ты можешь быть классным кодером, но без софт-скиллов — останешься «интровертным сеньором без влияния».
Ты сможешь влиять, если умеешь объяснить, услышать, вдохновить.
Продуктивность команд напрямую зависит от психологической безопасности — и ты можешь её самостоятельно формировать.
А еще спроси себя - кого повысят, из двух одинаково скиловых разработчиков? Того кто грамотно и без страха излагает свои мысли или того кто молчит или отвечает невпопад?
Поэтому, не стесняйся, пиши в комментариях, что ты думаешь об это статье! Прокачай навык
#motivation
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
https://hh.ru/vacancy/135709779
Я вот не понимаю, неужто кто-то соглашается на такие условия?🤪
Крутая, бл, команда.... 🤦♂️
Я вот не понимаю, неужто кто-то соглашается на такие условия?
Крутая, бл, команда.... 🤦♂️
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯1
Ло́уренс Джо́зеф «Ла́рри» Э́ллисон (англ. Lawrence Joseph «Larry» Ellison; род. 17 августа 1944 года, Бронкс, Нью-Йорк, США) — сооснователь и долгосрочный руководитель Oracle Corporation; ключевая фигура в развитии коммерческих СУБД и корпоративного программного обеспечения.
1958 — Pioneer 0 (Thor-Able) — первая американская попытка отправить аппарат к Луне; запуск 17 августа, авария на взлёте.
1970 — программа «Венера»: запуск аппарата Венера-7, первого успешно передавшего данные с поверхности другой планеты — Венеры.
1982 — Германия/Япония: на заводе Philips (Ганновер) начинают серийно прессовать первые компакт-диски (CD); коммерческий старт CD-эры — осень 1982.
#Biography #Birth_Date #Events #17Августа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2