最近写一个程序,从文件中读取一些字/词,然后存储起来供别的类引用。
对每个读入的词创建一个String,结果许多同样内容的也会存储多份,会占用大量内存。
开始的一个想法是使用map/set来存储所有遇到的词,这样就没有重复的了。然后别的类只需要引用这些词就可以了。
这样还需要一些工作量,经别人介绍,发现了String.intern方法。
例如下面代码
String a = new String("abc");
String b = new String("abc");
assertNotSame(a, b);
a和b是两个独立的对象,它们有各自的存储。所以not same。
但如果
String a = new String("abc").intern();
String b = new String("abc").intern();
assertSame(a, b);
此时assertSame就会pass。现在a和b其实是一个对象,a == b。它们只是同一个对象的两个名字。在debug时,可以看到他们的id是一样的。这样跟
String a = new String("abc");
String b = a;
assertSame(a, b);
效果是完全一样的。
intern是一个native的方法,但按照其文档解释,应该是JVM维护了一个当前进程曾经出现过的字符串的hash表,在调用intern时,会查询该表。如果已经存在,则直接返回对该String的引用;如果没有,则创建一个,并加入到hash中。
在我的代码中,因为是从文件中读取的词,所以只需要在读取词后,对每个词调用下intern再存储,就可以保证同样内容的字符串只有一份存储。更确切的说,只有一个对象。即不仅字符串内容只有一份,其overhead(String类的非内容部分,例如其他成员变量)也只有一份。
另外,如果使用字面量(literal)来定义字符串,则自动会调用intern,从而减少内存占用。例如:
String a = new String("abc");
String b = "abc";
String c = "abc";
assertSame(b, c);
assertNotSame(a, b);
对于字面量定义的b和c都会自动调用intern,(等用于String b = "abc".intern())。所以此时b和c是指向同一个对象。但a不是字面量定义的,所以是独立对象。
原文地址:http://www.cnblogs.com/zdwillie/archive/2013/10/23/3384766.html
分享到:
相关推荐
关于String.intern()方法,这个问题都被问烂了,有的文章在分析的时候还在用jdk1.7,jdk1.8之后内存模型发生了变化,内存的变化也会影响intern方法的执行,这里有必要写文章分析一下,请大家务必从头开始看,这样...
这篇文章将要讨论 Java 6 中是如何实现 String.intern 方法的,以及这个方法在 Java 7 以及 Java 8 中做了哪些调整。
String对象有个特殊的StringTable字符串常量池,为了减少Heap中生成的字符串的数量,推荐尽量直接使用String Table中的字符串常量池中的元素。 那么String.intern的性能怎么样呢?我们一起来看一下。 String.intern...
主要给大家介绍了关于C#中字符串优化String.Intern、IsInterned的相关资料,文中通过示例代码介绍的,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
主要介绍了通过String.intern()方法浅谈堆中常量池,在JDK7之前,字符串常量是存在永久带Perm 区的,JDK7开始在将常量池迁移到堆中,这个变化也导致了String的新特性,下面我们慢慢进行介绍。,需要的朋友可以参考下
深入理解 Java String#intern() 内存模型.docx
深入理解JavaString#intern()内存模型Java开发Java经验技巧共4页.pdf.zip
java中String类的intern、split方法的详细讲解。
主要给大家介绍了关于java String中intern的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
你可以使用自己定义的Map<String>(根据需要使用weak引用或者soft引用)并使用map中的值作为标准值来实现这个目标,或者你也可以使用JDK提供的String.intern()。 很多标准禁止在Java 6中使用String.intern()
大家知道,Java中string.intern()方法调用会先去字符串常量池中查找相应的字符串,如果字符串不存在,会在字符串常量池中创建该字符串然后再返回。 字符串常量池是一个固定大小的HashMap,桶的数量默认是1009, ...
受此问题的启发而被关闭:“ API请求:string.Intern(ReadOnlySpan ...)” 共享池已设置上限; 具有第二代LRU驱逐,以及第二代GC集合的进一步驱逐。 使用示例 馆藏 using Ben . Collections ; array = array . ...
String.intern()是一个Native方法,底层调用C++的 StringTable::intern 方法,源码注释:当调用 intern 方法时,如果常量池中已经该字符串,则返回池中的字符串;否则将此字符串添加到常量池中,并返回字符串的...
String s=new String("abc"); System.out.println(s); String s1="abc"; String s2=new String("abc"); System.out.println(s==s1);//false System.out.println(s==s2);//false System.out.println(s1==s2);...
pos文件是ProcessOn的源文件,可以导入后直接打开编辑。 内容是:不同jdk版本下对String的intern()的分析
String.intern 同一个字符串返回不同的引用 里面提及的 2021.11.21 部分内容修正 的测试用例
1、内存中的堆(stack)与栈(heap) 2、Java中数据在内存中的存储 基本数据类型的存储 对象的内存模型 包装类数据的存储 String类型数据的存储...4、String.intern() 5、关于equasl()与== 6、关于String是不可变的
string常量池和intern_韩雅茹Java系列2021.pdf