Skip to content

Commit 6666fbb

Browse files
KhArtNJavaenhorse
authored andcommitted
Добавлен пример для finalize()
1 parent ae1ff3a commit 6666fbb

1 file changed

Lines changed: 69 additions & 1 deletion

File tree

core.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,12 +773,80 @@ __Пул строк__ – это набор строк хранящийся в _
773773
[к оглавлению](#java-core)
774774

775775
## Что такое `finalize()`? Зачем он нужен?
776-
Через вызов метода `finalize()` JVM реализуется функциональность аналогичная функциональности деструкторов в С++, используемых для очистки памяти перед возвращением управления операционной системе. Данный метод вызывается при уничтожении объекта сборщиком мусора (_garbage collector_) и переопределяя `finalize()` можно запрограммировать действия необходимые для корректного удаления экземпляра класса - например, закрытие сетевых соединений, соединений с базой данных, снятие блокировок на файлы и т.д.
776+
Через вызов метода `finalize()` (который наследуется от Java.lang.Object) JVM реализуется функциональность аналогичная функциональности деструкторов в С++, используемых для очистки памяти перед возвращением управления операционной системе. Данный метод вызывается при уничтожении объекта сборщиком мусора (_garbage collector_) и переопределяя `finalize()` можно запрограммировать действия необходимые для корректного удаления экземпляра класса - например, закрытие сетевых соединений, соединений с базой данных, снятие блокировок на файлы и т.д.
777777

778778
После выполнения этого метода объект должен быть повторно собран сборщиком мусора (и это считается серьезной проблемой метода `finalize()` т.к. он мешает сборщику мусора освобождать память). Вызов этого метода не гарантируется, т.к. приложение может быть завершено до того, как будет запущена сборка мусора.
779779

780780
Объект не обязательно будет доступен для сборки сразу же - метод `finalize()` может сохранить куда-нибудь ссылку на объект. Подобная ситуация называется «возрождением» объекта и считается антипаттерном. Главная проблема такого трюка - в том, что «возродить» объект можно только 1 раз.
781781

782+
Пример:
783+
```java
784+
public class MainClass {
785+
786+
public static void main(String args[]) {
787+
TestClass a = new TestClass();
788+
a.a();
789+
a = null;
790+
a = new TestClass();
791+
a.a();
792+
System.out.println("!!! done");
793+
}
794+
}
795+
```
796+
```java
797+
798+
public class TestClass {
799+
800+
public void a() {
801+
System.out.println("!!! a() called");
802+
}
803+
804+
@Override
805+
protected void finalize() throws Throwable {
806+
System.out.println("!!! finalize() called");
807+
super.finalize();
808+
}
809+
}
810+
```
811+
Так как в данном случае сборщик мусора может и не быть вызван (в силу простоты приложения), то результат выполнения программы с большой вероятностью будет следующий:
812+
```
813+
!!! a() called
814+
!!! a() called
815+
!!! done
816+
```
817+
Теперь несколько усложним программу, добавив принудительный вызов Garbage Collector:
818+
```java
819+
public class MainClass {
820+
821+
public static void main(String args[]) {
822+
TestClass a = new TestClass();
823+
a.a();
824+
a = null;
825+
System.gc(); // Принудительно зовём сборщик мусора
826+
a = new TestClass();
827+
a.a();
828+
System.out.println("!!! done");
829+
}
830+
831+
}
832+
```
833+
Как и было сказано ранее, Garbage Collector может в разное время отработать, поэтому результат выполнения может разниться от запуска к запуску:
834+
Вариант а:
835+
```
836+
!!! a() called
837+
!!! a() called
838+
!!! done
839+
!!! finalize() called
840+
```
841+
Вариант б:
842+
```
843+
!!! a() called
844+
!!! a() called
845+
!!! finalize() called
846+
!!! done
847+
```
848+
849+
782850
[к оглавлению](#java-core)
783851

784852
## Что произойдет со сборщиком мусора, если выполнение метода `finalize()` требует ощутимо много времени, или в процессе выполнения будет выброшено исключение?

0 commit comments

Comments
 (0)