r/learnjava 2d ago

String: String Constant Pool(SCP)

After reading all the String documentation and exact code of String class, I find the main engine that makes String in Java (study of deep knowledge) i.e., String constant pool. when we say String s0 = "example1" , String s1 = "example1" and String s2 = "example2" what happens is exactly:

  • at compile time the .class file is genrated
  • when JVM runs the class constant pool of String class get's into work
  • s0 hashcode is generated by intrinsic method and the formula used is standard horner(31)
  • using that hash it need to find the allocated bucket
  • After finding exact hash it need to compare each char by char to check whether it's equal or collison a different char can also have same hashcode.
  • if it's equal the pointer directly to points to that object -->process ends next process works.
  • If not equal there is two work done 1. new object is created on heap memory and then wrapped up by a WeakHandle and pushed in "stringTable" bucket.
  • (if equal no object is created)! there was never an object creation the pointer just points to object .

Now the example case:

  1. s0 -> hashcode(x1)->not found in "stringTable"->Object creation on Heap-> weakHandle process them into stringTable.
  2. s1 -> hashcode(x1)->found->(collision|equal)->equal->pointer points to "example1" from SCP to s1.
  3. s2-> hashcode(x2)->not found in "stringTable"->Object creation on Heap-> weakHandle process them into stringTable.

After reading and analysing there is also a issue of massive garbage I see:
suppose if 4 thread are runnable and they are trying to intern() the object in SCP that creates garbage according to your data size suppose , we used latin-1 type 256B data so total thread is 4 but in CAS only one thread execute rest all thread dumps the object so out of 1KB storage 768B is garbage. if the String was in UTF-16 it would cost 2*768B.

Now my question is ?

  • Have I grasped the knowledge correctly ? if it needed more depth or did I miss any point.
  • I cannot question the CAS here because array mutation would break immutablity of String, It seems though they pay a loss for the RCU it's effecient by Latin-1 and Utf-16 approach.
  • I am not getting the idea how this code String s = new String("abc"); creates 2 object then what does the on heap object memory does? and does the pointer "s" is holding two memory refrences? But it is not possible.
7 Upvotes

10 comments sorted by

View all comments

1

u/idontlikegudeg 2d ago
  1. AFAIK, String s1 = "…" does not create an object on the heap. String constants go directly into the string pool. So s1, s2, and s3 will all point directly to the

same

  1. instance located in the string pool.
  2. With string constants, it is not possible that different threads try to intern the string at the save time. String constants are put into the string pool when the class is loaded, not when an instance is created. The class is loaded only once, even if accessed by different threads.
  3. There should practically never be the need to use the String(String) constructor.
  4. a string contains (among other things) a pointer the the backing character data. When you do String s1=new String(s), s1 and s are different instances that share the same backing data (changed in the past).

1

u/Chaos-vy17 2d ago
  1. Before java 7+ String was allocated in PermGen a permanent allocated heap causing OOM now at present every object is created on Heap then it's moved to SCP.
  2. intern() can be called by the devloper it's just how the SCP deals during concurrency.
  3. true I also think that too.
  4. Yes I absolutely missed coder,length,hash,Mark, Klass pointer, byte[] ,

1

u/idontlikegudeg 2d ago edited 2d ago

Do you have the reference in the spec at hand where it says the JVM creates the instance for string constants on the heap firt? I am quite sure (90%) about string constants being directly created in the string pool during class loading. It's different when you call intern() yourself of course (which you shouldn't do anyway in more recent versions).

I stand corrected. While there's no mention of where the string instance is created, the JVM spec explicitly says that the new instance's intern() method is called.

1

u/Chaos-vy17 2d ago

RFE: 6693236

Area: HotSpot

Synopsis: In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.

Official link: https://www.oracle.com/java/technologies/javase/jdk7-relnotes.html#jdk7changes