首页 > 编程知识 正文

java字符串过长,字符串常量的字符个数

时间:2023-05-05 22:36:50 阅读:119991 作者:850

前言先给出结论,不同点用红标

jdk1.6

)1)字符串数据存储在永久的世代中,new发出的字符串数据存储在堆中,字符串常量池中只存储指针数据

)2) new中出现的字符串在调用String.intern后:

如果没有与字符串常量池对应的数据,则堆中的字符串数据将复制到永久层代,并返回字符串常量池中的指针。

如果字符串常量池中有适当的数据,则直接返回字符串常量池中的指针

jdk1.7

)字符串数据存储在堆中,从new出来的字符串数据存储在堆中,字符串常量池中只存储指针数据

)2) new中出现的字符串在调用String.intern后:

如果没有与字符串常量池对应的数据,则会将堆中字符串数据的逻辑地址复制到堆中,并返回字符串常量池中的指针。

如果字符串常量池中有适当的数据,则直接返回字符串常量池中的指针

上面的大部分内容与《深入理解Java虚拟机》一致,但唯一有疑问的是intern的实现,因此以下仅证明intern

证明流程

以jdk1.6为例

)1)首先,按照openjdk下载方法下载各个版本的openjdk源代码,找到相应版本的JDK源代码

(2)找到String.intern实现) http://Hg.open JDK.Java.net/JDK6/JDK6/hotspot/file/d9c 3790 c 85 c1/src/share/vdk

JVM_entry(jstring,JVM_internstring ) jnienv*env,jstring str ) ) JVMwrapper('JVM_internstring ' ); jvmtivmobjectalloceventcollectoroam; if(str==null )返回空值; 如果//str为NULL,则返回NULL值oopstring=JNI handles 33603360 resolve _ non _ null (str ); op result=string table :3360 intern (string,CHECK_NULL ); //StringTable.intern是具体逻辑return(jstring ) JNI handles 3360: make _ local (env,result ); JVM_END

(3)再看看StringTable.intern的实现吧。 http://Hg.open JDK.Java.net/JDK6/JDK6/hotspot/file/d9c 3790 c 85 c1/src/share/d

op字符串表:3360 intern (symbol * symbol,TRAPS ) if ) symbol==null ) return NULL; 资源标记RM (thread; int length; jhar * chars=symbol-as _ unicode (length ); 从symbol获取字符串的指针Handle string; op result=intern (字符串、chars、length、CHECK_NULL ); 返回结果; } OOP string table :3360 intern (handle string _ or _ null,jchar* name,int len,TRAPS ) unsignedinthashvalue=hash//StringTable的序列下标oop found_string=the_table ()-lookup(index,name,len,hashValue ); 查一下是否有符合StringTable的字符串数据//如果有符合的字符串数据,直接输入if(found_string!=null (返回found _ string; debug _ only (stablememorycheckersmc (name,len*sizeof ) name[0] ); 资产(! universe :3360 heap (-is _ in _ reserved ) name|| GC _ locker 33603360 is _ active ),' proposednameofsymbol handle stre //trytoreusethestringifpossibleif (! string_or_null.is_null ()! 在avaobjectsinperm|||string _ or _ null (-is _ perm () StringTable中找不到相应的字符串,但如果字符串位于永久带中,则string=string_ 堆中的字符串数据string=Java _ lang _ string 33603360 create _ tenured _ from _ unicode (name,len, 复制che een (/grabthestringtable _ lockbeforegettingthe _ table ) ) becauseitcould//changeatsafepoint.mutexlockerml //将字符串添加到字符串表中。 其中return the _ table (-basic _ add (index,string,name,len,hashValue,check_name } ),与HashMap原理几乎相同

完成,jdk1.6,new中出现的字符串在调用String.intern后:

如果没有与字符串常量池对应的数据,则堆中的字符串数据将复制到永久层代,并返回字符串常量池中的指针。

如果字符串常量池中有适当的数据,则直接返回字符串常量池中的指针

同样,从jdk1.7开始,调用intern不会复制字符串数据

那么字符串常量池是什么样的数据结构? 为什么可以同时存储字符串数据和字符串的逻辑地址?

字符串常量池在StringTable内存空间中实现,StringTable只存储指针,不存储具体数据

综上所述:

)1) jdk1.6字符串常量池并不存储实际字符串数据,而是存储在具有永久带宽的区域中(由pspermgen 33603360 allocate _ permanent分配) );

)2) jdk1.7也同样,只有字符串数据存储在堆中

参考资料

3358 Java-performance.info/string-intern-in-Java-6-7-8 /

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。