The beauty of Java structure [2] -- destroy an object

Source: Internet
Author: User

Let's take a look at a piece of code:

Import java. util. arrays; import java. util. emptyStackException;/*** June 28, 2014 09:31:59 * @ author sunshine Xiaoqiang **/public class Stack {private Object [] elements; private int size = 0; private static final int DEFAULT_INITAL_CAPACITY = 15; public Stack () {elements = new Object [DEFAULT_INITAL_CAPACITY];} public void push (Object obj) {ensureCapacity (); elements [size ++] = obj ;} public Object pop () {if (size = 0) {throw new EmptyStackException ();} return elements [-- size];} /*** if the length exceeds the default length, double */private void ensureCapacity () {if (elements. length = size) {elements = Arrays. copyOf (elements, 2 * size + 1 );}}}
On the surface, this program has no errors, but it hides a "memory leak" problem. As a result, pop () pops up objects from the stack every time, however, the objects in the stack are still referenced, so they cannot be released in time. Modify the above Code as follows:

public Object pop(){if(size == 0){throw new EmptyStackException();}Object result = elements[--size];elements[size] = null;return result;}
Let's take a look at the Code:

import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStreamReader;public class IOTest {public static void main(String[] args) {try {FileInputStream fis = new FileInputStream("test.xml");InputStreamReader isr = new InputStreamReader(fis);BufferedReader br = new BufferedReader(isr);if(br.ready()){System.out.println(br.readLine());}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
The output result is as follows:

This Code does not seem to have any problems, but there is a memory leakage problem. We did not close the corresponding resources.


The Code is as follows:

Public class IOTest {public static void main (String [] args) {IOTest test = new IOTest (); IOTest. myThread myThread = test. new MyThread (); myThread. start (); test = null; // can this object be released? MyThread = null; // can a thread automatically end? Why ?} Class MyThread extends Thread {private int I = 0; @ Overridepublic void run () {while (true) {try {sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. out. println (I ++ );}}}}

Can the above objects be released? Can a thread automatically end?

Before figuring out the problem above, let's modify the above Code, first look at the following code:

Public class IOTest {private String data = "Sunshine Xiaoqiang"; public static void main (String [] args) {IOTest test = new IOTest ();/* IOTest. myThread myThread = test. new MyThread (); myThread. start (); */test = null; // can this object be released? // MyThread = null; // can a thread automatically end? Why? System. gc (); // start the Garbage Collector while (true) {}} class MyThread extends Thread {private int I = 0; @ Overridepublic void run () {while (true) {try {sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. out. println (I ++); System. out. println (data) ;}}@ Overrideprotected void finalize () throws Throwable {super. finalize (); System. out. println ("the object has been destroyed ");}}
In the above Code, we overwrite the finalize () method of the IOTest Object. This method is the Object class method (protected), which calls back this method when the Object's garbage collector executes it.

We used System. the gc () method is used to notify the Garbage Collector to recycle the garbage. The result of the operation is that "the object is destroyed ". next we will remove the comments in the above Code and start the thread and run it again.

Public class IOTest {private String data = "Sunshine Xiaoqiang"; public static void main (String [] args) {IOTest test = new IOTest (); IOTest. myThread myThread = test. new MyThread (); myThread. start (); test = null; // can this object be released? MyThread = null; // can a thread automatically end? Why? System. gc (); // start the Garbage Collector while (true) {}} class MyThread extends Thread {private int I = 0; @ Overridepublic void run () {while (true) {try {sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. out. println (I ++); System. out. println (data) ;}}@ Overrideprotected void finalize () throws Throwable {super. finalize (); System. out. println ("the object has been destroyed ");}}
The statement "the object has been destroyed" is not output to the console. This indicates that the IOTest object we created has not been destroyed. In many books, we will say that a null value is assigned to an object, this object will become a non-master object and will be recycled by the garbage collector. But why does this thread and IOTest object still exist? If so, how should we save our memory? Let's take a look at the Code:

Public class IOTest {private String data = "Sunshine Xiaoqiang"; public static void main (String [] args) {IOTest test = new IOTest (); IOTest. myThread myThread = test. new MyThread (); myThread. start (); test = null; // can this object be released? MyThread = null; // can a thread automatically end? Why? While (true) {try {Thread. sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. gc (); // start the Garbage Collector} class MyThread extends Thread {private int I = 0; @ Overridepublic void run () {while (I <5) {try {sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. out. println (I ++); System. out. println (data) ;}@overrideprotected void finalize () throws Throwable {super. finalize (); System. out. println ("the thread object has been destroyed") ;}} public void testUsed () {while (true) {}}@ Overrideprotected void finalize () throws Throwable {super. finalize (); System. out. println ("external Class Object destroyed ");}}

Output result:


From the above results, we can see that the thread object and the startup thread object can be truly recycled by the garbage collector only after the thread ends. Therefore, the thread class is defined in the internal class to start the thread, will always hold external class references. Now we have another question: Is it true that all internal classes hold external class references? Next we will try again:

Public class IOTest {private String data = "Sunshine Xiaoqiang"; public static void main (String [] args) {IOTest test = new IOTest (); IOTest. myThread myThread = test. new MyThread (); // myThread. start (); test = null; // can this object be released? // MyThread = null; // can a thread automatically end? Why? While (true) {try {Thread. sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. gc (); // start the Garbage Collector} class MyThread extends Thread {private int I = 0; @ Overridepublic void run () {while (I <5) {try {sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. out. println (I ++); System. out. println (data) ;}@overrideprotected void finalize () throws Throwable {super. finalize (); System. out. println ("the thread object has been destroyed") ;}} public void testUsed () {while (true) {}}@ Overrideprotected void finalize () throws Throwable {super. finalize (); System. out. println ("external Class Object destroyed ");}}
In the above code, I didn't start a thread, so MyThread can be treated as a common internal class. I set the reference of the external class to null, no results are output (indicating that the external class is not destroyed)

Public class IOTest {private String data = "Sunshine Xiaoqiang"; public static void main (String [] args) {IOTest test = new IOTest (); IOTest. myThread myThread = test. new MyThread (); // myThread. start (); test = null; // can this object be released? MyThread = null; // can a thread automatically end? Why? While (true) {try {Thread. sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. gc (); // start the Garbage Collector} class MyThread extends Thread {private int I = 0; @ Overridepublic void run () {while (I <5) {try {sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. out. println (I ++); System. out. println (data) ;}@overrideprotected void finalize () throws Throwable {super. finalize (); System. out. println ("the thread object has been destroyed") ;}} public void testUsed () {while (true) {}}@ Overrideprotected void finalize () throws Throwable {super. finalize (); System. out. println ("external Class Object destroyed ");}}
If I leave the internal class reference and the external class reference blank, the following results are output:


At least I can think from the above phenomenon that all internal classes hold references to external classes. This conclusion remains to be further verified...

Thank you for your attention to "Sunshine Xiaoqiang". I am honored to participate in another blog competition held by CSDN. If you feel that Xiaoqiang's blog is helpful to you, please cast your valuable vote for Xiaoqiang, voting address: http://vote.blog.csdn.net/Article/Details? Articleid = 30101091

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.