Java String Immutability storage when String object is changed
Asked Answered
T

2

9

I understood that if a String is initialized with a literal then it is allotted a space in String Pool and if initialized with the new Keyword it create a String's object. But I am confused with a case which is written below.

My question is what if a String is created with the new keyword and then it value is updated with a literal?

E.g.

String s = new String("Value1");  -- Creates a new object in heap space

then what if write the next statement as below.

s = "value2";

So my question is,

1 Will it create a String literal in a String Pool or it will update the value of that object?

2 If it creates a new literal in String Pool what will be happened to the currently existed object? Will it be destroyed or it will be there until the garbage collector is called.

This is a small string if the string is say of the thousands of characters then I am just worried about the space it uses. So my key question is for the space.

Will it immediately free the space from the heap after assigning the literal?

Can anyone explain what what value goes where from the first statement to the second and what will happened to the memory area (heap and String Pool).

Trustless answered 14/9, 2015 at 12:2 Comment(8)
Key to your question is - s is not an object. It's a reference to an object. You did changed the reference, but you didn't changed any objects here.Wedding
Also note that, String objects are immutable. Hence you can't update value of a String Object (directly. Reflection can be used to break immutability). In your particular case, String 'value1' which is on heap will be eligible for GC as soon as s is re-assigned. The String literal "Value1" will be eligible for GC when the class loader which loaded the class in which this literal is defined gets GCed.Myron
@DmitryZaitsev But according to the reference from which I read if it is initialized with new key word it will create a object in heap space. So there is a space occupied by the object. So what would be happened to that space when assigned a literal(which is not in heap space).Trustless
@Myron the statement (s="value2";) is valid(no compile or runtime error), it is allowing to update the value of s. So what will happened to the object space?Trustless
After change s = "value2"; object created via new String("Value1"); will be eligible to garbage collection.Schmuck
I am referring to the one stored in s (the one explicitly created via new operator).Schmuck
@Trustless - You are changing what the reference points to, not the value. :)Myron
examples.javacodegeeks.com/core-java/lang/string/… you can look this linkWelcher
V
9

Modifying Strings

The value is not updated when running

s = "value2";

In Java, except for the primitive types, all other variables are references to objects. This means that only s is pointing to a new value.

Immutability guarantees that the state of an object cannot change after construction. In other words, there are no means to modify the content of any String object in Java. If you for instance state s = s+"a"; you have creates a new string, that somehow stores the new text.

Garbage collection

This answer already provides an in-depth answer. Below a short summary if you don't want to read the full answer, but it omits some details.

By default new String(...) objects are not interned and thus the normal rules of garbage collection apply. These are just ordinary objects.

The constant strings in your code, which are interned are typically never removed as it is likely that eventually you will refer back to these.

There is however a side-note in the answer that sometimes classes are dynamically (un)loaded, in which case the literals can be removed from the pool.


To answer your additional questions:

Will it immediately free the space from the heap after assigning the literal?

No, that would not be really efficient: the garbage collector needs to make an analysis about which objects to remove. It is possible that you shared the references to your old string with other objects, so it is not guaranteed that you can recycle the object. Furthermore there is not much wrong with storing data no longer useful, as long as you don't need to ask additional memory to the operating system (compare it with you computer, as long as you can store all your data on your hard disk drive, you don't really have to worry about useless files, from the moment you would have to buy an additional drive, you will probably try to remove some files first). The analysis requires some computational effort. In general a garbage collector only runs when it (nearly) runs out of memory. So you shouldn't worry much about memory.

Can anyone explain what what value goes where from the first statement to the second and what will happened to the memory area (heap and String Pool).

Your first string:

String s = new String("Value1");

is a reference to the heap. If you call the command, it will allocate space on the heap for the string.

Now if you call:

s = "value2";

"value2" is an element of the String Pool, it will remain there until your program ends.

Since you don't have a reference to your old string (value1), anymore. That object is a candidate for collection. If the garbage collector later walks by, it will remove the object from the heap and mark the space as free.

Vitascope answered 14/9, 2015 at 12:11 Comment(0)
R
0

If you need to change a string, you can always create a new one that contains the modifications.

  • Java defines a peer class of String, called StringBuffer, which allows strings to be altered.
Ruminant answered 14/9, 2015 at 12:32 Comment(1)
I think this should be a comment, not an answer. I will not dv, but I guess some will :s.Vitascope

© 2022 - 2024 — McMap. All rights reserved.