Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String Creation and char array Memory Allocation

I have read a lot of conflicting articles regarding memory allocation when String is created. Some articles say that new operator creates a String in heap and String literal is created in String Pool [Heap] while some say that new operator creates an object in heap and another object in String pool.

In order to analyse this i wrote the below program which prints the hashcode of String char array and String object:

import java.lang.reflect.Field;

public class StringAnalysis {

    private int showInternalCharArrayHashCode(String s)
            throws SecurityException, NoSuchFieldException,
            IllegalArgumentException, IllegalAccessException {
        final Field value = String.class.getDeclaredField("value");
        value.setAccessible(true);
        return value.get(s).hashCode();
    }

    public void printStringAnalysis(String s) throws SecurityException,
            IllegalArgumentException, NoSuchFieldException,
            IllegalAccessException {
        System.out.println(showInternalCharArrayHashCode(s));

        System.out.println(System.identityHashCode(s));

    }

    public static void main(String args[]) throws SecurityException,
            IllegalArgumentException, NoSuchFieldException,
            IllegalAccessException, InterruptedException {
        StringAnalysis sa = new StringAnalysis();
        String s1 = new String("myTestString");
        String s2 = new String("myTestString");
        String s3 = s1.intern();
        String s4 = "myTestString";

        System.out.println("Analyse s1");
        sa.printStringAnalysis(s1);

        System.out.println("Analyse s2");
        sa.printStringAnalysis(s2);

        System.out.println("Analyse s3");
        sa.printStringAnalysis(s3);

        System.out.println("Analyse s4");
        sa.printStringAnalysis(s4);

    }

}

This program prints following output:

Analyse s1
1569228633
778966024
Analyse s2
1569228633
1021653256
Analyse s3
1569228633
1794515827
Analyse s4
1569228633
1794515827

From this output one thing is very clear that irrespective of how String is created, if Strings have same value then they share same char array.

Now my question is where is this chararray stored , is it stored in heap or it goes to permgen? Also i want to understand how to diferentiate between heap memory addresses and permgen memory addresses.

I have a big issue if it is stored in permgen as it will eat up my precious limited permgen space. and if char array is not stored in permgen but in heap then does it imply that String literals also use heap space [which is something i have never read] .

like image 808
Lokesh Avatar asked Apr 22 '13 16:04

Lokesh


1 Answers

From String src

 public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

it's clear that the string created with this constructor shares the char array (value) with the original string.

It's important to note that the API does not guarantee this sharing:

Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable

For example, String.substring used to share char array with the original string, but in latest versions of Java 1.7 String.substring makes a copy of char array.

like image 120
Evgeniy Dorofeev Avatar answered Oct 27 '22 00:10

Evgeniy Dorofeev