Create new object and select older object for garbage collection - java

In the code snippet below, new String object will be created to to store the modified new string as Strings are immutable in java. But i'm not sure which one will create new object and which one of them will be marked for garbage collection?
String s1 = "It";
String s2 = "was";
String s3 = s1+" "+s2;
s2+=" roses";
s3 = s3+s2+" roses all the way";
System.out.println(s3);

It depends on scope of your code snippet.
If all code is inside one method all of them will be in garbage after execution.
Garbage Collector works on count of references to the object.
As example you declare a new reference String s1 inside a method and assign to something. Then method executed and upon completion there is no more references. So, go to garbage.

This is a brief, basic explanation, the actual behavior can vary based on compiler and JVM used. Also there are a lot of articles available that go into this topic in depth and can provide more detailed explanations.
These literals will be put in the JVM's string pool and never be GC'ed. (i.e. they will exist in memory for the duration of the JVM.
"It", "was", " ", " roses", " roses all the way"
Then, as far as the String references are concerned, It depends on the scope of the variables. I will assume local method level for this answer:
String s1 = "It"; // a reference will be created on the stack
String s2 = "was"; // a reference will be created on the stack
String s3 = s1+" "+s2; // a reference will be created on the stack for s3, and then two temp objects will be created in memory, one for s1+" ", one for concatenating the result with +s2. (this operation can vary greatly based on how compiler optimizes), the first one will become eligible for GC immediately.
s2+=" roses"; // same as above.
s3 = s3+s2+" roses all the way"; // same as above but the object s3 was pointing to will become eligible for GC immediately.
System.out.println(s3); // no memory allocation.
When the method ends, s1, s2, and s3 references will be cleared from the stack and any remaining objects pointed to become eligible for GC.
Hope this helps, remember this is a very basic explanation, I recommend reading up on this topic, as how it will actually behave can vary greatly depending on how the compiler decides to optimize. (For example, the compiler may see all these temporary references and concatenations are not needed and discard them)
Note: Since you are concatenating to create strings, you may want to consider the Mutable alternatives like StringBuffer or StringBuilder which can help optimize.

Related

Java String Immutability storage when String object is changed

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).
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.
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.

Total Number of String objects created in the process?

String str1="JAVA";
String str2="JAVA";
String str3=new String("JAVA");
String str4=new String("JAVA").intern();
2 objects will be created. str1 and str2 refer to same object because of String literal pool concept and str3 points to new object because using new operator and str4 points to the same object points by str1 and str2 because intern() method checks into string pool for string having same value.
str1=str2=str3=str4=null;
One object will be eligible for GC. That is the object created through String str3=new String("JAVA"). The first String object is always accessible through reference stored in string literal pool.
Is my explanation correct?
Total Number of String objects created in the process?
Three: The one in the intern pool created via the literal and the two you create via new String.
One object will be eligible for GC.
I count two, and possibly even all three under very special circumstances:
The one you created in this line:
String str3=new String("JAVA");
(since you later set str3 to null).
The one you created temporarily in this line:
String str4=new String("JAVA").intern();
That line creates a new String object, calls intern on it, and then saves a reference to the string from the pool. So in theory, it creates a String object that is immediately available for GC. (The JVM may be smart enough not to do that, but that's the theory.)
Possibly, eventually, under the right conditions, even the string in the intern pool. Contrary to popular belief, strings in the intern pool are available for garbage collection as we can see from the answer to this other question. Just because they're in the permgen (unless you're using Oracle's JVM 7 or later) that doesn't mean they're not GC'd, since the permgen is GC'd too. So the question becomes: When or how is a string literal used in code no longer referenced? I don't know the answer, but I think a reasonable assumption would be: When and if the class using it is unloaded from memory. According to this other answer, that can only happen if both the class and its classloader are unloaded (and may not happen even then). If the class was loaded by the system classloader (the normal case), then presumably it's never unloaded.
So almost certainly just two (#1 and #2 above), but it was fun looking into #3 as well.

How to make sure String objects are garbage collected in Java

Here is the code snippet.
method(){
String s1="abc";
String s2 = new String ("abc");
s1=null;
s2=null;
--------
---------
}
At the end is s1 & s2 objects are exists? How you will make sure these objects are garbage collected ?
Objects referenced to by s1 and s2 are eligible for garbage collection once s1=null and s2=null provided that no other references to that Object exists or when the method exits, provided that the Objects were only referenced by the local variables.An object once created uses some memory and the memory remains allocated till there are references for the use of the object.When there are no references for an object, it is assumed to be no longer needed and the memory occupied by the object *can be reclaimed.*An Object becomes eligible for Garbage collection or GC if its not reachable from any live threads or any static refrences in other words you can say that an object becomes eligible for garbage collection if its all references are null.
There are methods like System.gc() and Runtime.gc() which is used to send request of Garbage collection to JVM but it’s not guaranteed that garbage collection will happen. Java programmers can not force Garbage collection in Java; it will only trigger if JVM thinks it needs a garbage collection. Forced GC is sign of bad coding.Once should in turn always look to minimize creation of unnecessary objects and references to those objects.
They get garbage Collected after they go out of scope.
Unless you're actually having serious performance issues, I'd stop worrying about it so much and let the garbage collector do it's thing.
You should be careful though, there are some kinds of elements such as file streams, open sockets, and such that are not managed like that. you have to close those.
If the question is how to make sure, the answer is fairly simple. You can never make sure that any object will be garbage collected. Read this to understand what garbage collection really is and how to reason about it.
If the question is how to hint for a collection, then set all the references of unwanted objects to null and call System.gc(), which will request (not force) a collection. Nothing is guaranteed to be released using this method, but often it's the closest thing you can get.
If you want to do this specifically for strings, because they may contain sensitive data or something along these lines, use a char[] to store that data instead of a String, because you can change the primitive values of the array at will and erase them when you're done.
Garbage collector runs periodically(time period is JVM dependent). Java maintains table of objects and its references when reference is broken (probably by assigning null to reference) then on next execution of GC (garbage collector) object's having no reference will be deleted (If something goes wrong with GC then object will not garbage collected - very very rare condition), which is totally dependent on JVM. You can send request to JVM to run GC by using following code (Processing your request is once again JVM dependent):
Runtime.getRuntime().gc();
or
System.gc();
Programmer don't have to worry about the running GC mostly JVM will handle execution of GC. There are lots of enhancements made to the garbage collectors. Java (latest version) comes with G1(Garbage First) collector which is a server-style garbage collector which runs more effectively. G1 is a great replacement for CMS (Concurrent Mark-Sweep Collector).
If you want to know more about garbage collector then you should read the pages:
[http://docs.oracle.com/javase/7/docs/technotes/guides/vm/gc-ergonomics.html][1]
[http://docs.oracle.com/javase/7/docs/technotes/guides/vm/cms-6.html][2]
[http://docs.oracle.com/javase/7/docs/technotes/guides/vm/par-compaction-6.html][3]
String s2 = new String ("abc");
Here 'abc' will be created in regular, garbage collectible heap area.
So as soon as you make S2 null, this string object is eligible for garbage collection.
This is assuming that your programm do not have any other reference to this particular string object "abc".
String s1="abc";
In this case, "abc" will be created in special area of heap called literal pool or string pool. Making "abc" null does not make "abc" eligible for garbage collection since JVM will try to reuse this "abc" in future.
Baseline in this case is, normal garbage collection rules won't apply here.
Hope this helped. :-)

Object Management in String Pool ofJava

Hi i am working in java and want to know how String objects are created in the String pool
and how they are managed.
So in the following example i am creating two Strings s and s1,so can anyone explain me how many Objects are created in LIne1?Also how many Objects are eligible for garbage collection in Line3?
String s = "x" + "y";//Line 1
String s1 = s;//Line 2
s = null;//Line 3
Only one object is created "xy" . compiler does it for optimization.
No object is eligible for garbage collection.
It would create one object xy in the String constant pool area. As "x"+"y" would be evaluated during compilation. Additionally, garbage collector cannot access String constant pool area.
Reference: https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

Regarding string object pool in PermGC

I heard that string object pool exists in the PermGC and when a string intern is executed, it checks the pool first to see if an equivalent string object exists, if it does not exist, it creates one and returns a reference to the pooled instance.
But here is my first question.
I think that object is created on the heap, especially in the young generation first. If it survives during few garbage collections, it moves to the old generation. can anybody explain how the string object goes to the pool that exists in the Perm GC?
second question:
String s = "test";
s = "test1";
If i reassign "test1" to a reference s and continue to use "test1", does it mean that "test" (created on the young generation) will be garbage collected?
third question:
How is the string object pool related to the runtime constant pool?
Thanks.
What makes you think the interned String first goes to the young generation? The String#intern() method is a native method. It's certainly very possible for an implementation to move it right into the permgen.
Second question: if there's no other references to that "test" String instance, it's eligible for garbage collection. Same story if it's interned. Even an interned String that no longer has any active references can be garbage collected. This might not have been the case in older JVMs, though. And it can be implementation-specific, I guess.
As for the third question, I do not know. All I know is that String literals from source code are placed into the same pool. If you were to construct a String that's equal to a String constant from source and then intern it, you'd be returned the instance that was used to represent the constant. Think of this as String literals having been interned right away.
EDIT: just read your initial few sentences again and I think I see the reason for the confusion. When you call intern() on a String, and no equal String is in the pool yet, then it's not first gonna construct an equivalent String. It'll just move the instance you called intern() on to the pool rather than returning a new reference. That's how it's stated in the JavaDoc.
Strings go to intern pool in two cases:
you explicitly call intern() method on the String object
you initialize it with a literal (you give the explicit content of the String), since Java automatically interns String literals.
The pool is organized as a table, once a String is interned it is added to the pool if the value is not yet present otherwise a reference to the existing entry is used.
"test" in your case is supposed to go to the pool and not to the young space, anyway cleanup of Strings not referenced anymore is performed there too (I cannot say if it is part of the same GC process used for the heap nor if this behavior is standard)

Categories

Resources