You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: core.md
+69-1Lines changed: 69 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -773,12 +773,80 @@ __Пул строк__ – это набор строк хранящийся в _
773
773
[к оглавлению](#java-core)
774
774
775
775
## Что такое `finalize()`? Зачем он нужен?
776
-
Через вызов метода `finalize()` JVM реализуется функциональность аналогичная функциональности деструкторов в С++, используемых для очистки памяти перед возвращением управления операционной системе. Данный метод вызывается при уничтожении объекта сборщиком мусора (_garbage collector_) и переопределяя `finalize()` можно запрограммировать действия необходимые для корректного удаления экземпляра класса - например, закрытие сетевых соединений, соединений с базой данных, снятие блокировок на файлы и т.д.
776
+
Через вызов метода `finalize()`(который наследуется от Java.lang.Object) JVM реализуется функциональность аналогичная функциональности деструкторов в С++, используемых для очистки памяти перед возвращением управления операционной системе. Данный метод вызывается при уничтожении объекта сборщиком мусора (_garbage collector_) и переопределяя `finalize()` можно запрограммировать действия необходимые для корректного удаления экземпляра класса - например, закрытие сетевых соединений, соединений с базой данных, снятие блокировок на файлы и т.д.
777
777
778
778
После выполнения этого метода объект должен быть повторно собран сборщиком мусора (и это считается серьезной проблемой метода `finalize()` т.к. он мешает сборщику мусора освобождать память). Вызов этого метода не гарантируется, т.к. приложение может быть завершено до того, как будет запущена сборка мусора.
779
779
780
780
Объект не обязательно будет доступен для сборки сразу же - метод `finalize()` может сохранить куда-нибудь ссылку на объект. Подобная ситуация называется «возрождением» объекта и считается антипаттерном. Главная проблема такого трюка - в том, что «возродить» объект можно только 1 раз.
781
781
782
+
Пример:
783
+
```java
784
+
publicclassMainClass {
785
+
786
+
publicstaticvoidmain(Stringargs[]) {
787
+
TestClass a =newTestClass();
788
+
a.a();
789
+
a =null;
790
+
a =newTestClass();
791
+
a.a();
792
+
System.out.println("!!! done");
793
+
}
794
+
}
795
+
```
796
+
```java
797
+
798
+
publicclassTestClass {
799
+
800
+
publicvoida() {
801
+
System.out.println("!!! a() called");
802
+
}
803
+
804
+
@Override
805
+
protectedvoidfinalize() throwsThrowable {
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:
Как и было сказано ранее, 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
+
782
850
[к оглавлению](#java-core)
783
851
784
852
## Что произойдет со сборщиком мусора, если выполнение метода `finalize()` требует ощутимо много времени, или в процессе выполнения будет выброшено исключение?
0 commit comments