Java for Beginner
672 subscribers
541 photos
155 videos
12 files
827 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Всем доброго субботнего утра!☀️

Ничего больше писать не буду, все равно никто не отвечает😂

Просто хороших выходных каждому и даром!🍻🖐
Хоть какая то польза от работы программистом😂😂😂

https://t.me/Java_for_beginner_dev

#Mems
This media is not supported in your browser
VIEW IN TELEGRAM
Всем доброго утра!🖐

Сегодня в 16:00 по МСК, мы вновь соберемся, что покодить)))
Сегодня мы напишем чат, и попробуем запустить его для работы через удаленный сервер!
😱

Жду всех, будет интересно!)
Ссылка на встречу опубликована в нашем чате - https://t.me/Java_Beginner_chat

Присоединяйтесь!
Создаем свой чат! Размещаем его на удаленном сервере.

Запись нашей сегодняшней встречи -
YOUTUBE
RUTUBE

Спасибо огромное тем кто пришел, я правда старался для Вас) Надеюсь все понравилось! 🙏

На сегодняшней встрече с подписчиками, мы создали клиент - серверный чат, и разместили сервер чата на удаленном виртуальном сервере! Рассмотрели на примере работу с библиотекой Swing, классом Socket и многопоточкой)))

Код на GitHUB - https://github.com/Oleborn/ChatProject.git

Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!

Всем хорошего вечера и отличного общения! 🫡✌️
Сборка мусора в Java

Сборка мусора (Garbage Collection, GC) — это автоматический процесс управления памятью, который освобождает объекты, больше не используемые программой. Главная задача GC — найти объекты, которые недостижимы, и освободить занимаемую ими память для повторного использования. Программистам в Java не нужно вручную управлять выделением и освобождением памяти (как, например, в языках C/C++), что значительно упрощает разработку и снижает количество ошибок, связанных с утечками памяти.

Память в Java разделена на две основные части: кучу (Heap) и стек (Stack). Объекты, создаваемые динамически (например, при вызове new), размещаются в куче и занимают определенное место до тех пор, пока они не станут недостижимыми. Если ненужные объекты не будут удаляться, память заполнится, что приведет к сбою программы из-за OutOfMemoryError.

Garbage Collector автоматически отслеживает и удаляет такие объекты, поддерживая память в чистоте и предотвращая утечки.

Основные концепции сборки мусора

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

Достижимость объектов:
Объект считается достижимым, если на него есть ссылки из активных частей программы (например, глобальные переменные или переменные метода).
Недостижимый объект — это объект, на который нет ссылок, и он не может быть использован в дальнейшем.


Корни GC (GC Roots):
GC Roots — это специальные точки входа, от которых начинается проверка достижимости объектов.
Примеры GC Roots: активные потоки, статические поля классов, локальные переменные методов, ссылки из JNI (Java Native Interface).


Алгоритмы сборки мусора:
Существуют различные алгоритмы для отслеживания достижимости объектов: маркировка и удаление (Mark and Sweep), копирование (Copying), сжатие (Compaction) и другие.
Алгоритмы также могут отличаться по стратегии: минорная (Minor GC) и полная сборка (Full GC).


Молодое и старое поколения (Young и Old Generation):

Java-куча делится на несколько регионов:
Young Generation — область, в которой создаются новые объекты. В эту область чаще всего попадает сборка мусора.
Old Generation — сюда перемещаются более «долгоживущие» объекты. Сборка в этом регионе происходит реже, но является более затратной.


Как работает сборка мусора в JVM?

Java использует комбинацию разных алгоритмов и стратегий для эффективного управления памятью:

Mark and Sweep:
Основной алгоритм, используемый в большинстве JVM.
Маркировка (Mark): GC проходит по всем доступным объектам и помечает их как "достижимые".
Удаление (Sweep): Все объекты, которые не были помечены, удаляются.


Copying:
Этот алгоритм используется в Eden-области (молодое поколение).
Вся Young Generation делится на Eden и два Survivor пространства (From и To).
Когда Eden заполняется, GC перемещает все активные объекты в Survivor To область и очищает Eden.


Generational Garbage Collection:
JVM разделяет память на разные поколения:
Young Generation — для новых объектов.
Old Generation — для объектов, которые пережили несколько сборок.
Объекты перемещаются из Young в Old по мере увеличения их "возраста".


Compact and Defragmentation:
После удаления недостижимых объектов память может стать фрагментированной.
Для предотвращения фрагментации, GC может выполнять сжатие (compaction), перемещая объекты в соседние участки памяти.


#Java #Training #Medium #Garbage_collector
Типы сборок мусора в Java

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


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


Parallel GC (или Throughput Collector):
Использует несколько потоков для сборки мусора.
Хорош для многопоточных приложений, стремящихся минимизировать время пауз.


CMS (Concurrent Mark-Sweep):
Предназначен для минимизации пауз при сборке мусора.
Выполняет маркировку и удаление объектов одновременно с выполнением программы.

Более ресурсоемкий и требует больше CPU.

G1 (Garbage First):

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


ZGC и Shenandoah:
Современные сборщики мусора с низкими паузами.
Ориентированы на большие кучи и высокую производительность.
Особенности сборки мусора в разных регионах памяти


Память в JVM делится на несколько регионов, каждый из которых имеет свои особенности:

Young Generation:
Основные области: Eden, Survivor From, Survivor To.
В этой области происходят минорные сборки (Minor GC) — сборки, которые удаляют недостижимые объекты в молодом поколении.


Old Generation:
Сюда попадают объекты, которые "пережили" несколько минорных сборок.
Сборка в этой области называется Full GC или Major GC и является более затратной по времени.


Permanent Generation (Metaspace):
Содержит метаинформацию, загружаемые классы и методы.
В более новых версиях JVM (с Java 8) эта область была заменена на Metaspace, которая динамически расширяется по мере необходимости.


#Java #Training #Medium #Garbage_collector
Что выведет код?

import java.util.*;

public class Task141024 {
public static void main(String[] args) {
List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "orange"));
list.add(1, "grape");
list.set(2, "pear");

for (Iterator<String> it = list.iterator(); it.hasNext();) {
String fruit = it.next();
if (fruit.equals("pear")) {
it.remove();
}
}

System.out.println(list);
}
}


#Tasks
Я знаю человека который тоже так функционирует... 😂😂🤪

https://t.me/Java_for_beginner_dev

#Mems
Внутреннее устройство Garbage Collector

Garbage Collector в Java работает на основе трех основных принципов:

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


1. Поиск недостижимых объектов
Каждый объект в Java находится в куче, и на него указывают ссылки (references). GC определяет объекты, которые больше не используются, с помощью концепции достижимости (Reachability). В JVM есть специальные точки, называемые корнями GC (GC Roots), от которых начинается проверка достижимости объектов.

Примеры GC Roots:
Локальные переменные и параметры метода.
Статические поля классов.
Ссылки из JNI (Java Native Interface).
Активные потоки.
Алгоритм маркировки и удаления (Mark and Sweep) проходит по GC Roots и помечает все объекты, до которых можно дотянуться. Недостижимые объекты (не помеченные) считаются кандидатами для удаления.


2. Освобождение памяти

После маркировки всех достижимых объектов начинается этап удаления. В зависимости от используемого GC, могут применяться разные стратегии удаления:
Сборка с переносом (Copying) — применимо в молодом поколении (Young Generation).
Удаление без компактизации — объекты удаляются, но места остаются фрагментированными.
Компактизация — память сжимается, перемещая все объекты в одну часть кучи.


3. Компактизация и дефрагментация

Когда объекты удаляются из памяти, в куче остаются «пустые» фрагменты, которые приводят к фрагментации. Некоторые GC, такие как G1 или Serial GC, выполняют компактизацию, чтобы переместить оставшиеся объекты и освободить непрерывный блок памяти. Компактизация полезна для улучшения производительности при выделении памяти новым объектам.

Виды Garbage Collector и их внутреннее устройство

Каждый сборщик мусора в JVM имеет свои особенности и алгоритмы, которые влияют на производительность и паузы приложения. Рассмотрим основные GC и их внутренние механизмы:

Serial GC:
Самый простой алгоритм, использующий однопоточную сборку мусора.
Сначала выполняет маркировку, затем удаляет недостижимые объекты и сжимает оставшиеся объекты.
Используется в основном для небольших приложений или однопоточных систем.


Parallel GC:
Многопоточная версия Serial GC.
Параллельно выполняет маркировку и удаление объектов.
Эффективно работает в многопроцессорных системах.


CMS (Concurrent Mark-Sweep):
Выполняет асинхронную сборку мусора, минимизируя паузы.

Этапы работы:
Initial Mark — быстрая маркировка активных объектов.
Concurrent Mark — параллельная маркировка всех достижимых объектов.
Concurrent Sweep — удаление недостижимых объектов.
Избегает компактизации, что может привести к фрагментации.


G1 GC (Garbage First):
Разделяет память на множество небольших регионов.
Выполняет параллельную сборку в приоритетных регионах.
Объединяет алгоритмы маркировки, удаления и сжатия.
Оптимизирован для минимизации пауз.


ZGC:
Сборщик мусора с нулевыми паузами.
Использует механизм цветной маркировки (Coloring) для управления памятью.
Работает на больших объемах памяти и в многопоточных приложениях.


Shenandoah:
Также минимизирует паузы за счет выполнения конкурентного перемещения объектов.
В отличие от ZGC, реализует дополнительные стратегии для снижения влияния на приложение.


#Java #Training #Medium #Garbage_collector
Внешнее управление сборщиком мусора

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

Выбор алгоритма GC:
-XX:+UseSerialGC — включает Serial GC.
-XX:+UseParallelGC — включает Parallel GC.
-XX:+UseConcMarkSweepGC — включает CMS.
-XX:+UseG1GC — включает G1 GC.
-XX:+UseZGC — включает ZGC.


Настройка размеров памяти:
-Xms<size> — начальный размер кучи.
-Xmx<size> — максимальный размер кучи.
-XX:NewSize=<size> — размер молодого поколения.
-XX:MaxNewSize=<size> — максимальный размер молодого поколения.


Параметры управления метасферой (Metaspace):
-XX:MetaspaceSize=<size> — начальный размер метасферы.
-XX:MaxMetaspaceSize=<size> — максимальный размер метасферы.


Вывод информации о работе GC:

-XX:+PrintGCDetails — выводит детализированную информацию о сборках мусора.
-Xlog:gc* — в Java 9 и выше используется для логирования событий GC.
-XX:+HeapDumpOnOutOfMemoryError — создаёт дамп памяти при ошибке OutOfMemoryError.


Примеры управления GC с параметрами JVM

Допустим, у нас есть Java-приложение с высоким потреблением памяти. Мы хотим минимизировать паузы GC и эффективно использовать ресурсы.

Запуск с G1 GC и детальным логированием:
java -Xms2g -Xmx4g -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCTimeStamps MyApp
Этот запуск включает G1 GC, устанавливает начальный размер кучи на 2 ГБ и максимальный на 4 ГБ, а также выводит подробные логи.


Диагностика и мониторинг работы GC


Понимание поведения сборщика мусора требует мониторинга его работы в реальном времени. Для этого существуют различные инструменты:

JVisualVM:
Графический инструмент для мониторинга памяти, потоков и GC.
Позволяет отслеживать метрики производительности и визуализировать сборки мусора.


JConsole:
Встроенный инструмент для мониторинга JVM.
Позволяет контролировать использование памяти, сборку мусора и состояние потоков.


GC Logs:
Логирование работы GC позволяет анализировать частоту и продолжительность сборок.
Для Java 8 и выше рекомендуется использовать параметр -Xlog:gc*.


JFR (Java Flight Recorder):
Мощный инструмент профилирования, который записывает метрики производительности, использование памяти и действия GC.
Запускается с параметром -XX:StartFlightRecording.


Пример анализа логов:
java -Xms1g -Xmx2g -XX:+UseG1GC -Xlog:gc:gc.log -XX:+PrintGCDetails MyApp
После выполнения мы можем открыть файл gc.log и проанализировать все события, связанные с GC, например, частоту минорных и мажорных сборок, продолжительность пауз и использование памяти.


Пример программы, создающей большое количество объектов, чтобы увидеть работу разных сборщиков мусора:
public class GCExample {
public static void main(String[] args) {
for (int i = 0; i < 10_000_000; i++) {
createObjects();
}
}

private static void createObjects() {
String[] strings = new String[1000];
for (int i = 0; i < strings.length; i++) {
strings[i] = new String("Object " + i);
}
}
}


Запустите эту программу с разными настройками GC, чтобы увидеть, как меняется поведение:
java -Xms512m -Xmx1g -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps GCExample


#Java #Training #Medium #Garbage_collector
Мусорные ссылки в Java

В Java существует механизм управления памятью, который включает использование ссылок для работы с объектами. В дополнение к обычным ссылкам на объекты, Java предоставляет особый тип ссылок, называемый мусорными ссылками (Garbage References), который позволяет более гибко управлять памятью и поведением объектов в условиях автоматической сборки мусора.

Мусорные ссылки (или гибкие ссылки) представляют собой четыре основных типа ссылок: сильные (Strong), мягкие (Soft), слабые (Weak) и фантомные (Phantom). Эти типы ссылок определяют, каким образом объекты могут быть удалены сборщиком мусора и как приложения могут использовать эту информацию для управления ресурсами.

1. Сильные ссылки (Strong References)

Сильные ссылки — это стандартный тип ссылок в Java. Они используются по умолчанию при создании объектов и препятствуют сборке мусора. Пока объект доступен через сильную ссылку, сборщик мусора никогда не удалит его из памяти.

Пример сильной ссылки:
StringBuilder sb = new StringBuilder("Hello, World!");
В данном примере переменная sb ссылается на объект типа StringBuilder. Пока существует ссылка sb, объект не может быть удален сборщиком мусора, даже если больше ни одна часть программы не обращается к нему.


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

2. Мягкие ссылки (Soft References)

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

Пример использования мягкой ссылки:
import java.lang.ref.SoftReference;

public class SoftReferenceExample {
public static void main(String[] args) {
// Создаем сильную ссылку на объект
String strongReference = new String("Hello, World!");

// Создаем мягкую ссылку на объект
SoftReference<String> softReference = new SoftReference<>(strongReference);

// Убираем сильную ссылку
strongReference = null;

// Получаем объект из мягкой ссылки
if (softReference.get() != null) {
System.out.println("Object is still in memory: " + softReference.get());
} else {
System.out.println("Object has been collected by GC.");
}
}
}
Если памяти достаточно, вывод будет: Object is still in memory: Hello, World!. Но если память заканчивается, объект будет удален, и ссылка softReference.get() вернет null.


#Java #Training #Medium #Garbage_References
3. Слабые ссылки (Weak References)

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

Пример использования слабой ссылки:
import java.lang.ref.WeakReference;

public class WeakReferenceExample {
public static void main(String[] args) {
// Создаем сильную ссылку на объект
String strongReference = new String("Weak Reference Example");

// Создаем слабую ссылку на объект
WeakReference<String> weakReference = new WeakReference<>(strongReference);

// Убираем сильную ссылку
strongReference = null;

// Вызываем сборщик мусора
System.gc();

// Проверяем наличие объекта в памяти
if (weakReference.get() != null) {
System.out.println("Object is still in memory: " + weakReference.get());
} else {
System.out.println("Object has been collected by GC.");
}
}
}


В большинстве случаев, если сразу после удаления сильной ссылки вызывается сборщик мусора, то вывод будет: Object has been collected by GC.
Слабые ссылки активно применяются в таких структурах, как WeakHashMap, для реализации автоматического удаления объектов, которые больше не используются.


4. Фантомные ссылки (Phantom References)

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


Фантомные ссылки нельзя использовать для доступа к объекту напрямую. Вместо этого они помещаются в очередь ссылок (ReferenceQueue) и ожидают обработки.

Пример использования фантомных ссылок:
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;

public class PhantomReferenceExample {
public static void main(String[] args) {
String phantomReferenceString = new String("Phantom Reference Example");

// Создаем очередь для фантомных ссылок
ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();

// Создаем фантомную ссылку
PhantomReference<String> phantomReference = new PhantomReference<>(phantomReferenceString, referenceQueue);

// Удаляем сильную ссылку
phantomReferenceString = null;

// Вызываем сборщик мусора
System.gc();

// Проверяем, помещена ли фантомная ссылка в очередь
Reference<? extends String> ref = referenceQueue.poll();
if (ref != null) {
System.out.println("Object has been collected and reference is in the queue.");
} else {
System.out.println("Object is not yet collected by GC.");
}
}
}
В этом примере вывод покажет, что фантомная ссылка была добавлена в очередь после удаления объекта. Это означает, что объект был удален из памяти, и теперь его можно использовать для выполнения дополнительных действий.


Применение мусорных ссылок

Кэширование:
Мягкие ссылки позволяют эффективно управлять кэшами, автоматически удаляя данные при нехватке памяти.

Очистка ресурсов:
Фантомные ссылки применяются для очистки ресурсов, таких как файлы и потоки.

Сборка объектов:
Слабые ссылки полезны для автоматического удаления объектов из коллекций, таких как WeakHashMap, и для реализации пулов объектов.

Отслеживание состояния объектов:
Фантомные ссылки позволяют определить, когда объект окончательно удален из памяти.

#Java #Training #Medium #Garbage_References
Что выведет код?

public class Task151024 {
static Task151024 obj;

public static void main(String[] args) {
Task151024 m1 = new Task151024();
Task151024 m2 = new Task151024();

m1 = null;
obj = m2;
m2 = null;

System.gc();
System.out.println("Done");
}

@Override
protected void finalize() {
System.out.println("Object collected");
}
}


#Tasks
И это не только про девопсов😞🤪

https://t.me/Java_for_beginner_dev

#Mems
Утечка памяти в Java

Утечка памяти — это состояние в приложении, когда объекты, которые больше не используются, продолжают оставаться в памяти, не подлежащие сборке мусора. В отличие от традиционных языков программирования, таких как C/C++, Java имеет встроенный сборщик мусора (Garbage Collector), который автоматически освобождает память, занятую ненужными объектами. Однако это не гарантирует, что утечки памяти полностью исключены.

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

1. Что такое утечка памяти в Java?

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


Пример классической утечки памяти:
import java.util.ArrayList;
import java.util.List;

public class MemoryLeakExample {
private static List<Object> list = new ArrayList<>();

public static void main(String[] args) {
// Создаем утечку памяти, добавляя объекты в список, но никогда их не удаляя
while (true) {
list.add(new Object());
}
}
}
В этом примере список list продолжает расти, так как новые объекты постоянно добавляются, но никогда не удаляются. В итоге программа столкнется с OutOfMemoryError.


2. Виды утечек памяти в Java

Утечки памяти в Java можно классифицировать на несколько основных типов:

2.1 Постепенная утечка (Heap Leaks)

Этот тип утечки возникает, когда объекты продолжают оставаться в памяти, даже если они больше не используются. Например, большие коллекции, которые постепенно увеличиваются и никогда не очищаются.
public class GradualMemoryLeak {
private static List<String> cache = new ArrayList<>();

public void addData() {
for (int i = 0; i < 1000; i++) {
cache.add("Data-" + i);
}
}
}
Если метод addData вызывается многократно без очистки списка cache, то список будет постоянно увеличиваться, вызывая утечку памяти.


2.2 Утечка в статических полях (Static Field Leaks)

Статические поля живут на протяжении всего времени работы приложения и, если на объект ссылается статическое поле, объект также не подлежит сборке мусора.
public class StaticFieldMemoryLeak {
private static List<Object> staticList = new ArrayList<>();

public void addObject(Object obj) {
staticList.add(obj);
}
}
Здесь статическое поле staticList сохраняет все добавленные объекты, и они никогда не удаляются, что приводит к утечке памяти.


2.3 Утечка в слушателях (Listener Leaks)

Этот тип утечки происходит, когда слушатели (listeners) или наблюдатели (observers) не удаляются после завершения работы. Например, при использовании событийных моделей или слушателей интерфейсов (GUI-компоненты, потоки).
public class EventListenerMemoryLeak {
public static void main(String[] args) {
JFrame frame = new JFrame("Example");
JButton button = new JButton("Click Me");
button.addActionListener(e -> System.out.println("Button clicked!"));

frame.add(button);
frame.setSize(200, 200);
frame.setVisible(true);
// Закрываем окно, но слушатель остается в памяти
frame.dispose();
}
}
В этом примере, если не удалить слушатели ActionListener перед dispose(), объект button и все связанные объекты будут продолжать удерживаться в памяти.


#Java #Training #Medium #Memory_Leak
2.4 Утечка в потоках (Thread Leaks)

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

public class ThreadMemoryLeak {
public void createThread() {
Thread thread = new Thread(() -> {
try {
Thread.sleep(10000); // Ожидание в течение длительного времени
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
}
}
Если потоки создаются многократно и не завершаются корректно, то их память будет постепенно заполняться.


3. Методы обнаружения утечек памяти

Для диагностики и предотвращения утечек памяти в Java можно использовать несколько методов:


Профайлеры: Инструменты, такие как VisualVM, Eclipse MAT, и JProfiler, позволяют отслеживать использование памяти и находить объекты, которые занимают много места.
Анализ дампа памяти (Heap Dump): Дамп памяти представляет собой снимок текущего состояния кучи JVM. Его можно проанализировать с помощью jmap или инструментов, таких как Eclipse MAT.
Инструменты для мониторинга: Использование jconsole, jvisualvm или других инструментов для мониторинга позволяет наблюдать за временем жизни объектов и отслеживать изменения.


Пример использования jmap для создания дампа памяти:
jmap -dump:format=b,file=heap_dump.hprof <PID>


4. Способы предотвращения утечек памяти

Чтобы предотвратить утечки памяти в Java, рекомендуется следовать следующим принципам:


Удаление ненужных ссылок:
Освобождайте ссылки на объекты, как только они больше не нужны.

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

Статические поля сохраняют объекты на протяжении всего времени работы приложения.

Удаление слушателей:
Удаляйте слушатели (listeners) и наблюдатели (observers), когда они больше не нужны.

Использование WeakReference и SoftReference:
Для объектов, которые можно удалять при недостатке памяти, используйте слабые и мягкие ссылки.

Проверка потоков:

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

Применение try-with-resources:
Использование try-with-resources для закрытия ресурсов, таких как потоки и соединения, предотвращает утечки ресурсов.

Пример корректного использования try-with-resources:
import java.io.*;

public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
System.out.println(reader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
В этом примере ресурс автоматически закрывается, даже если возникает исключение.


#Java #Training #Medium #Memory_Leak
Всем доброго вечера!✌️

Завтра мы начинаем изучение фреймворка Spring. 🎉

Сразу хотелось бы ответить на несколько вопросов:
- Все ли основные темы мы рассмотрели в JavaCore?
Конечно же нет! Осталось много разделов и классов о которые мы задели лишь краями. Будем ли мы их рассматривать еще? Конечно! Но уже факультативно, по наитию или по Вашей просьбе вне основного течения постов.
- Почему Spring?
Потому что это основной фреймворк который висит в 80% предложений о работе на hh.ru. Изучив его хотя-бы поверхностно, Вы значительно увеличиваете свои шансы получить желаемый оффер на junior позицию!

Задавайте еще вопросы, постараюсь на все ответить.

Всем вкусного гранита программирования🤓
Spring Framework

Spring Framework – это мощный, легковесный и гибкий фреймворк с открытым исходным кодом, широко используемый для разработки Java-приложений. Он был создан для упрощения процесса разработки корпоративных приложений, обеспечения инверсии управления (IoC), а также для внедрения зависимостей (DI). Spring предлагает разнообразный набор инструментов и шаблонов, упрощающих создание, тестирование и внедрение программ.

Основные цели Spring Framework:

Упрощение разработки: Spring снимает с разработчика множество рутинных задач, таких как управление объектами, конфигурация приложения и обеспечение транзакций.
Гибкость: Разработчики могут свободно выбирать, какие компоненты использовать и в какой степени.
Модульность: Spring построен по модульному принципу, что позволяет включать только необходимые части фреймворка.
Тестирование: Поддержка тестирования компонентов изолированно и без дополнительных зависимостей.


Основные концепции Spring Framework:

Inversion of Control (IoC) – Инверсия управления. Этот принцип означает, что процесс создания объектов и управления их зависимостями перекладывается на фреймворк, а не осуществляется вручную.
Dependency Injection (DI) – Внедрение зависимостей. DI является одной из реализаций IoC, которая позволяет передавать зависимости (например, другие объекты) в класс через конструктор или сеттеры, делая классы менее связными.
Aspect-Oriented Programming (AOP) – Аспектно-ориентированное программирование. AOP используется для разделения сквозной логики (например, логирования, безопасности, транзакционного управления), обеспечивая высокую степень модульности и повторного использования кода.
Transaction Management – Управление транзакциями. Spring упрощает работу с транзакциями, абстрагируя разработчиков от реализации конкретных API, таких как JDBC или JPA.


Пример кода Spring Framework: Внедрение зависимостей через аннотации
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;

// Компонент класса
@Component
class Engine {
public void start() {
System.out.println("Engine is starting...");
}
}

// Компонент класса, где внедряется зависимость Engine
@Component
class Car {
private final Engine engine;

@Autowired
public Car(Engine engine) {
this.engine = engine;
}

public void drive() {
engine.start();
System.out.println("Car is driving...");
}
}

// Конфигурация Spring Context
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext("com.example");
Car car = context.getBean(Car.class);
car.drive();
}
}
В этом примере Car зависит от компонента Engine, и Spring автоматически внедряет его в объект Car. Благодаря аннотации @Autowired, зависимости передаются автоматически, снижая связность классов и упрощая конфигурацию приложения.


Преимущества использования Spring Framework:


Модульность: Spring предоставляет ряд модулей, таких как Spring Core, Spring MVC, Spring Security и Spring Data, что позволяет использовать только те компоненты, которые необходимы для конкретного проекта.
Тестируемость: С помощью Spring легко создавать тесты для приложения, поскольку внедрение зависимостей упрощает создание фиктивных (mock) объектов.
Гибкость конфигурации: Конфигурация приложения может выполняться через XML-файлы, Java-классы или аннотации, что обеспечивает гибкость и масштабируемость.
Широкая экосистема: Spring интегрируется с множеством других фреймворков и библиотек, таких как Hibernate, JPA, Quartz и многими другими.
Поддержка транзакций: Простая интеграция с платформами управления транзакциями позволяет автоматизировать процессы, обеспечивая атомарность и целостность данных.


#Java #Training #Spring