其他分享
首页 > 其他分享> > StringTable

StringTable

作者:互联网

String的基本特性

public class StringTest {
    @Test
    public void  test1(){
        String s1="abc";//字面量定义的方式,“abc”存储在字符串常量池中
        String s2="abc";
        System.out.println(s1==s2);//地址判断
        s2="hello";//此时,是在字符串常量池中重新造一个“hello”,不是在原来的“abc”的基础好上修改
        System.out.println(s1==s2);//地址判断
        System.out.println(s1);
        System.out.println(s2);
    }
    @Test
    public void  test2(){
        String s1="abc";//字面量定义的方式,“abc”存储在字符串常量池中
        String s2="abc";
        s2+="def";//这里也不是在原来的“abc”的基础上修改,而是重新造一个
        System.out.println(s1==s2);//地址判断
        System.out.println(s1);
        System.out.println(s2);
    }

    @Test
    public void  test3(){
        String s1="abc";//字面量定义的方式,“abc”存储在字符串常量池中
        String s2=s1.replace("a","x");//生成一个新的字符串常量“xbc”,而不是在“abc”的基础上修改
        System.out.println(s1==s2);//地址判断
        System.out.println(s1);
        System.out.println(s2);
    }
}

如图,设置虚拟机启动参数(我使用的jdk8):-XX:StringTableSize=1008

得到系统错误提示:

Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
StringTable size of 1008 is invalid; must be between 1009 and 2305843009213693951

 

String的内存分配

事例代码:

    /**
     * 在jdk6中:
     * -XX:PermSize=6m -XX:MaxPermSize=6m -Xmx6m -Xms6m
     *
     * 在jdk8中:
     * -XX:MetaspaceSize=6m -XX:MaxMetaspaceSize=6m -Xmx6m -Xms6m
     */
    public static void main(String[] args) {
        //使用Set保持对常量的应用,避免发生Full GC时常量被回收
        Set<String> set=new HashSet<String>();
        int i=0;
        while (true){
            set.add(java.lang.String.valueOf(i++).intern());
        }
    }

将jdk设置成1.6,永久代最大内存设置成6m:

抛出异常:系统提示是永久代的内存不足了

Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
	at java.lang.String.intern(Native Method)
	at com.booyue.tlh.StringTest.main(StringTest.java:51)

接下来我们把jdk设置成1.8,然后把元空间和堆内存设置的6m:

抛出异常:系统提示是堆空间的内存不足了

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.HashMap.resize(HashMap.java:703)
	at java.util.HashMap.putVal(HashMap.java:662)
	at java.util.HashMap.put(HashMap.java:611)
	at java.util.HashSet.add(HashSet.java:219)
	at com.booyue.tlh.StringTest.main(StringTest.java:51)

 

字符串的拼接操作

实例代码

public class StringTableTest {
    @Test
    public void test1() {
        String s1 = "javaEE";
        String s2 = "hadoop";

        String s3 = "javaEEhadoop";
        String s4 = "javaEE" + "hadoop";//编译器优化,等同于javaEEhadoop

        //如果拼接符号前后出现了变量,则需要在堆空间中new 一个StringBuilder,具体的内容为拼接之后的结果:javaEEhadoop
        /**
         * 具体操作细节:
         *  1.StringBuilder s5=new StringBuilder( );
         *  2.s5.append("javaEE");
         *  3.s5.append("hadoop");
         *  s5.toString( )//StringBuilder的toString()方法其实就是new 的一个String对象
         */
        String s5 = s1 + "hadoop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;

        System.out.println(s3 == s4);//true
        System.out.println(s3 == s5);//false
        System.out.println(s3 == s6);//false
        System.out.println(s3 == s7);//false
        System.out.println(s5 == s6);//false
        System.out.println(s5 == s7);//false
        System.out.println(s6 == s7);//false
        //inern()方法会判断字符串常量池中是否存在:javaEEhadoop,如果存在就返回常量池javaEEhadoop的地址
        //如果在常量池中不存在:javaEEhadoop,则在常量池中加载一份:javaEEhadoop,并返回对象的地址
        String s8 = s6.intern();
        System.out.println(s3 == s8);//true
    }
}

 

Intern( )方法

 

其他

查看StringTable统计信息,JVM参数:-XX:+PrintStringTableStatistics

StringTable statistics:
Number of buckets       :     60013 =    480104 bytes, avg   8.000
Number of entries       :      4021 =     96504 bytes, avg  24.000
Number of literals      :      4021 =    358352 bytes, avg  89.120
Total footprint         :           =    934960 bytes
Average bucket size     :     0.067
Variance of bucket size :     0.067
Std. dev. of bucket size:     0.259
Maximum bucket size     :         3

 

 

标签:String,常量,StringTable,System,println,字符串,out
来源: https://blog.csdn.net/qq_27062249/article/details/117092729