Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What happens in Java when the object is no longer used and is not assigned to null?

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "what happens when the object is no longer used and is not assigned to null in Java", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn what happens when objects are no longer used and are not assigned to null in Java.

Preface

Many Java developers have heard the phrase "unused objects should be manually assigned to null", and many developers have always believed in this phrase. Most of the answers are "help GC recover memory earlier and reduce memory footprint," but you can't answer it any further.

In view of the fact that there are too many misleading about this problem on the Internet, this article will deeply analyze the significance of the operation "assign null when the object is no longer in use" through an example for your reference. Try not to use technical terms in this article, but you still need to have some idea of JVM.

Sample code

Let's look at a very simple piece of code:

Public static void main (String [] args) {if (true) {byte [] placeHolder = new byte [64 * 1024 * 1024]; System.out.println (placeHolder.length / 1024);} System.gc ();}

We instantiated an array placeHolder in if, then passed System.gc () outside the scope of if; we manually triggered GC, which is intended to recycle placeHolder, because placeHolder is no longer accessible. Look at the output:

65536 [GC 68239K-> 65952K (125952K), 0.0014820 secs] [Full GC 65952K-> 65881K (125952K), 0.0093860 secs]

Full GC 65952K-> 65881K (125952K) means: after this GC, the memory footprint has been reduced from 65952K to 65881K. It actually means that GC didn't recycle the placeHolder, isn't it incredible?

Let's take a look at following the fact that "unused objects should be manually assigned to null":

Public static void main (String [] args) {if (true) {byte [] placeHolder = new byte [64 * 1024 * 1024]; System.out.println (placeHolder.length / 1024); placeHolder = null;} System.gc ();}

Its output is:

65536 [GC 68239K-> 65952K (125952K), 0.0014910 secs] [Full GC 65952K-> 345K (125952K), 0.0099610 secs]

After this GC, the memory footprint dropped to 345K, that is, the placeHolder was successfully recycled! Comparing the two pieces of code, simply assigning placeHolder to null solves the GC problem, thanks to "unused objects should be manually assigned to null".

Wait, wait, This is the crux of the problem.

Runtime stack

Typical runtime stack

If you understand the principle of compilation, or the underlying mechanism of program execution, you will know that when the method is executed, the variables (local variables) in the method are assigned on the stack; of course, for Java, the object out of new is in the heap, but there will also be a pointer to this object in the stack, just like int.

For example, for the following code:

Public static void main (String [] args) {int a = 1; int b = 2; int c = a + b;}

The state of its runtime stack can be understood as:

Index variable 1a2b3c

"Index" represents the sequence number of the variables in the stack, and the variables are placed on the stack sequentially according to the order in which the code within the method is executed.

Another example is:

Public static void main (String [] args) {if (true) {int a = 1; int b = 2; int c = a + b;} int d = 4;}

At this point, the runtime stack is:

Index variable 1a2b3c4d

Is it easy to understand? In fact, if you think carefully about the runtime stack of the above example, there is room for optimization.

Stack Optimization of Java

In the above example, the main () method takes up four stack index space when it runs, but it doesn't actually take up that much. When the if is executed, the variables a, b, and c are no longer accessible, so the stack index of 1x3 they occupy can be "recycled", such as this:

Index variable 1a2b3c1d

Variable d reuses the stack index of variable a, which saves memory space.

A reminder

The words "runtime stack" and "index" above are deliberately invented for ease of introduction. In fact, in JVM, their names are "local variable table" and "Slot", respectively. And the local variable table is determined at compile time, so you don't need to wait until "run time".

A glimpse of GC

Here's a quick look at a very simple piece of mainstream GC: how to make sure that objects can be recycled. Another expression is how to determine that the object is alive.

If you think about it, in the world of Java, there is an association between objects, and we can access from one object to another. As shown in the figure.

When you think about it, the reference relationship between these objects and objects is like a big picture; more clearly, there are many trees.

If we find all the roots, then if we go down from the roots, we can find all the living objects, then those who have not been found will be dead! So GC can recycle those objects.

The question now is, how do you find the roots? JVM has long stipulated that one of them is the object referenced in the stack. That is, as long as the object in the heap is still referenced in the stack, it is considered to be alive.

A reminder

The algorithm described above to determine that an object can be recycled is called the Reachability Analysis algorithm.

JVM's "bug"

Let's go back to the original example:

Public static void main (String [] args) {if (true) {byte [] placeHolder = new byte [64 * 1024 * 1024]; System.out.println (placeHolder.length / 1024);} System.gc ();}

Take a look at its runtime stack:

LocalVariableTable: Start Length Slot Name Signature 0 21 0 args [Ljava/lang/String; 5 12 1 placeHolder [B

The first index in the stack is the method input parameter args of type String [], and the second index is placeHolder with type byte [].

Referring to the previous content, we infer that the reason why placeHolder is not recycled is System.gc (); when GC is triggered, there are references to args and placeHolder in the runtime stack of the main () method, and GC determines that both objects are alive and are not recycled. That is to say, after leaving if, the code has left the scope of placeHolder, but after that, there is no read or write to the runtime stack, and the index in which placeHolder is located has not been reused by other variables, so GC determines that it is alive.

To verify this inference, we declare another variable before System.gc ();, which reuses placeHolder's index according to the "stack optimization of Java" mentioned earlier.

Public static void main (String [] args) {if (true) {byte [] placeHolder = new byte [64 * 1024 * 1024]; System.out.println (placeHolder.length / 1024);} int replacer = 1; System.gc ();}

Take a look at its runtime stack:

LocalVariableTable: Start Length Slot Name Signature 0 23 0 args [Ljava/lang/String; 5 12 1 placeHolder [B 19 4 1 replacer I

Unsurprisingly, replacer reuses placeHolder's index. Take a look at GC:

65536 [GC 68239K-> 65984K (125952K), 0.0011620 secs] [Full GC 65984K-> 345K (125952K), 0.0095220 secs]

PlaceHolder has been successfully recycled! Our inference has also been verified.

From the run-time stack, adding int replacer = 1; has the same effect as assigning placeHolder to null: disconnect the placeHolder from the stack in the heap and let GC determine that placeHolder is dead.

Now that we've figured out the principle that unused objects should be manually assigned to null, it all comes from a "bug" of JVM: when code leaves the scope of a variable, it doesn't automatically sever its connection to the heap. Why does this "bug" always exist? Don't you think the probability of this happening is too small? It's kind of a tradeoff.

At this point, I believe you have a deeper understanding of "what happens when an object is no longer used in Java and is not assigned to null". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report