search
HomeJavajavaTutorialHow to use Java object destruction and finalize methods

Destruction of objects

In C, the destructor method is used to release resources and destroy the object itself.

In Java, due to the existence of GC, we do not need to manually reclaim memory, which greatly reduces the workload and improves the security of the program. But Java does have a function similar to the destructor in C.

finalize method

Overload this method to perform some operations when the class is recycled by GC.

The following is an example of a class implementing finalize.

The Aoo class has an int and a String property, overloads toString and prints the object and its creation time in the construction, and prints the object and the calling time in finalize.

Aoo Class

public class Aoo {
       private int id;
       private String name;

       public Aoo(){
              this(0, null);
       }

       public Aoo(int id, String name){
              this.id = id;
              this.name = name;
              System.out.println(this.toString() + " now create:" + System.currentTimeMillis());
       }
        /*
        * 省略get/set/toString
        */
       protected void finalize() throws Throwable{
              super.finalize();
              System.out.println(this.toString() + "now finalize:" + System.currentTimeMillis());
       }
}

First, a simple test

main method

public class FinalizeTest {
       public static void main(String[] args) throws Exception {
              Aoo a = new Aoo(1, "a");
              a = null;
              System.gc()
              Thread.sleep(2000);
              System.exit(0);
       }
}

Print the result :

id:1 name:a now create:1497547723036
id:1 name:anow finalize:1497547724059

GC recycling of objects

Here the GC is manually called to clean up the memory, and if you comment out System.gc();, the printed result is like this:

id:1 name:a now create:1497547846923

In other words, without specifically calling the GC, the finalize method is not called at all, which means that the object is not actively recycled at all.

Contrary to imagination, GC operates in a lazy manner. That is to say, when there is no place in the memory, GC will not actively recycle objects. In order to verify this idea, I created a Threads are used to continuously consume memory and do not actively call GC.

ThreadA class

public class ThreadA implements Runnable{
       public void run() {
              List<Integer> list = new ArrayList<Integer>();
              int i = 0;
              while(true){
                     list.add(i);
                     i++;
              }
       }
}

main method

public class FinalizeTest {
       public static void main(String[] args) throws Exception {
              Aoo a = new Aoo(1, "a");
              a = null;
              ThreadA ta = new ThreadA();
              Thread t = new Thread(ta);
              t.start();
              Thread.sleep(2000);
              System.exit(0);
       }
}

Print result:

id: 1 name:a now create:1497548135268
id:1 name:anow finalize:1497548135386

Although GC was not called manually this time, the finalize method still ran, that is to say, only if The GC will only run when the memory is consumed and the GC needs to clean up the memory.

Such a finalize method is indeed unreliable. It is not even sure whether it can be called, let alone complete any specific operation. If you need to close the stream and recover resources, it is better to call a method manually, or in Resources are released uniformly in the final block.

In the finalize method, should you reassign a reference to yourself to avoid being recycled by GC?

Try to re-reference in the finalize method to prevent GC from recycling

The modified Aoo is as follows

public class Aoo {
       public static Aoo SAVE = null;
       private int id;
       private String name;

       public Aoo(){
              this(0, null);
       }

       public Aoo(int id, String name){
              this.id = id;
              this.name = name;
              System.out.println(this.toString() + " now create:" + System.currentTimeMillis());
       }  
       /*
        * 省略get/set/toString
        */
       protected void finalize() throws Throwable{
              super.finalize();
              System.out.println(this.toString() + "now finalize:" + System.currentTimeMillis());
              SAVE = this;
       }
}

main method

public class FinalizeTest {
       public static void main(String[] args) throws Exception {
              Aoo.SAVE = new Aoo(1, "a");
              Aoo.SAVE = null;
              System.gc();
              Thread.sleep(500);
              System.out.println(Aoo.SAVE == null? "a is dead" : "a is alive" );              
              System.exit(0);             
       }
}

Print result:

id:1 name:a now create:1497551409195
id:1 name:anow finalize:1497551409201
a is alive

It can be seen here that the Aoo.SAVE object is indeed "resurrected", but this operation is limited. If the same trick is repeated, the object will not be "resurrected" again.

main method

public class FinalizeTest {
       public static void main(String[] args) throws Exception {
              Aoo.SAVE = new Aoo(1, "a");
              Aoo.SAVE = null;
              System.gc();
              Thread.sleep(500);
              System.out.println(Aoo.SAVE == null? "a is dead" : "a is alive" );

              Aoo.SAVE = null;
              System.gc();
              Thread.sleep(500);
              System.out.println(Aoo.SAVE == null? "a is dead" : "a is alive" );

              System.exit(0);          
       }
}

Print result:

id:1 name:a now create:1497551587715
id:1 name :anow finalize:1497551587721
a is alive
a is dead

Note here that the two operations are the same, and the finalize method will only be called once by the system.

What will happen if an infinite loop occurs in the finalze method?

Aoo class

public class Aoo {
       private int id;
       private String name;

       public Aoo(){
              this(0, null);
       }

       public Aoo(int id, String name){
              this.id = id;
              this.name = name;
              System.out.println(this.toString() + " now create:" + System.currentTimeMillis());
       }
       /*
        * 省略get/set/toString
        */
       protected void finalize() throws Throwable{
              super.finalize();
              while(true){
                     System.out.println(this.toString() + "now finalize:" + System.currentTimeMillis());
                     Thread.sleep(100);
              }
       }
}

main method

public class FinalizeTest {
       public static void main(String[] args) throws Exception {
              Aoo a1 = new Aoo(1 , "a1");
              Aoo a2 = new Aoo(2 , "a2");
              a1 = null;
              a2 = null;
              ThreadA ta = new ThreadA();
              Thread t = new Thread(ta);
              t.start();
              Thread.sleep(5000);

              System.exit(0);
       }
}

Print result:

id: 1 name:a1 now create:1497552024252
id:2 name:a2 now create:1497552024252
id:1 name:a1now finalize:1497552024373
id:1 name:a1now finalize:1497552024503
id: 1 name:a1now finalize:1497552026848
id:1 name:a1now finalize:1497552028960
id:1 name:a1now finalize:1497552032363

The result is random and sometimes executed The finalize of a1 is sometimes executed by a2.

This result illustrates two points:

1. The thread priority of the finalze method is very low, and the time interval is quite uncertain and significantly greater than 100 milliseconds.

2. This infinite loop causes the finalize method of other objects to fail to execute.

If there is such an infinite loop in object creation, will it cause the object to be unable to be destroyed and cause memory overflow?

We create a large number of Aoo objects and wait for the GC to reclaim the memory by itself.

In order to visually observe the calling of the finalize method, the printing code when the Aoo object is initialized is deleted.

main method

public class FinalizeTest {
       public static void main(String[] args) throws Exception {
              int i = 1;
              while(true){
                     Aoo a = new Aoo(i , "a" + i);
                     i++;
              }
       }
}

Let the program execute for about two minutes, then terminate it manually and check the output

1497554225913
id:269614 name:a269614now finalize:1497554226151
id:269614 name:a269614now finalize:1497554227635
id:269614 name:a269614now finalize:1497554227735
id:269614 name:a269614now finalize:1497554227836
id:269614 name:a269614now finalize:1497554229586
id:269614 name:a269614now finalize:1497554229686
id:269614 name:a269614now finalize:1497554229951
id:269614 name:a269614now finalize:1497554230051
id:269614 name:a269614now finalize:1497554230152
id:269614 name:a269614now finalize:1497554233699
id:269614 name:a269614now finalize:1497554233800
id:269614 name:a269614now finalize:1497554233900
id:269614 name:a269614now finalize:1497554234308
id:269614 name:a269614now finalize:1497554234408
id:269614 name:a269614now finalize:1497554234508
id:269614 name:a269614now finalize:1497554235053
id:269614 name:a269614now finalize:1497554235153
id:269614 name:a269614now finalize:1497554235253
id:269614 name:a269614now finalize:1497554235823
id:269614 name:a269614now finalize:1497554235923
id:269614 name:a269614now finalize:1497554236023
id:269614 name:a269614now finalize:1497554240324
id:269614 name:a269614now finalize:1497554240424
id:269614 name:a269614now finalize:1497554240525
id:269614 name:a269614now finalize:1497554241146
id:269614 name:a269614now finalize:1497554241247
id:269614 name:a269614now finalize:1497554241347
id:269614 name:a269614now finalize:1497554241448
id:269614 name:a269614now finalize:1497554242020
id:269614 name:a269614now finalize:1497554242120
id:269614 name:a269614now finalize:1497554242220
id:269614 name:a269614now finalize:1497554242321
id:269614 name:a269614now finalize:1497554242421
id:269614 name:a269614now finalize:1497554242521
id:269614 name:a269614now finalize:1497554248367
id:269614 name:a269614now finalize:1497554248467
id:269614 name:a269614now finalize:1497554248567
id:269614 name:a269614now finalize:1497554248667
id:269614 name:a269614now finalize:1497554249534
id:269614 name:a269614now finalize:1497554249634
id:269614 name:a269614now finalize:1497554249734
id:269614 name:a269614now finalize:1497554249835
id:269614 name:a269614now finalize:1497554255954
id:269614 name:a269614now finalize:1497554256055
id:269614 name:a269614now finalize:1497554256155
id:269614 name:a269614now finalize:1497554256255
id:269614 name:a269614now finalize:1497554256356
id:269614 name:a269614now finalize:1497554257285
id:269614 name:a269614now finalize:1497554257386
id:269614 name:a269614now finalize:1497554257486
id:269614 name:a269614now finalize:1497554257586
id:269614 name:a269614now finalize:1497554257686
id:269614 name:a269614now finalize:1497554268652
id:269614 name:a269614now finalize:1497554268753
id:269614 name:a269614now finalize:1497554268853
id:269614 name:a269614now finalize:1497554268953
id:269614 name:a269614now finalize:1497554269054
id:269614 name:a269614now finalize:1497554269154
id:269614 name:a269614now finalize:1497554277474
id:269614 name:a269614now finalize:1497554292852
id:269614 name:a269614now finalize:1497554301062

可以发现两个情况:

1.只有一个对象的finalize方法被执行了,也就是说这个死循环的finalize方法阻止了其他对象执行finalize方法

2.程序执行很快的一段时间后,finalize方法就开始执行,但是随着内存消耗的不断增加,finalize方法被执行的次数也就越来越少。

The above is the detailed content of How to use Java object destruction and finalize methods. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:亿速云. If there is any infringement, please contact admin@php.cn delete
带你搞懂Java结构化数据处理开源库SPL带你搞懂Java结构化数据处理开源库SPLMay 24, 2022 pm 01:34 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

Java集合框架之PriorityQueue优先级队列Java集合框架之PriorityQueue优先级队列Jun 09, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

完全掌握Java锁(图文解析)完全掌握Java锁(图文解析)Jun 14, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

一起聊聊Java多线程之线程安全问题一起聊聊Java多线程之线程安全问题Apr 21, 2022 pm 06:17 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

Java基础归纳之枚举Java基础归纳之枚举May 26, 2022 am 11:50 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

详细解析Java的this和super关键字详细解析Java的this和super关键字Apr 30, 2022 am 09:00 AM

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

Java数据结构之AVL树详解Java数据结构之AVL树详解Jun 01, 2022 am 11:39 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于平衡二叉树(AVL树)的相关知识,AVL树本质上是带了平衡功能的二叉查找树,下面一起来看一下,希望对大家有帮助。

java中封装是什么java中封装是什么May 16, 2019 pm 06:08 PM

封装是一种信息隐藏技术,是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法;封装可以被认为是一个保护屏障,防止指定类的代码和数据被外部类定义的代码随机访问。封装可以通过关键字private,protected和public实现。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.