本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告

戒除浮躁,读好书,交益友


我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:邢红瑞的blog
日志总数:523
评论数量:1142
留言数量:0
访问次数:9693776
建立时间:2004年12月20日




[jvm]深入JVM(一):从"abc"=="abc"看java的连接过程
原创空间,  软件技术,  电脑与网络

邢红瑞 发表于 2007/4/24 23:46:22

一般说来,我不关注java底层的东西,这次是一个朋友问到了,注意不光是  System.out.println("abc"=="abc");返回true, System.out.println(("a"+"b"+"c").intern()=="abc");也返回true;这和java的连接过程有关。java解析CONSTANT_String_info时,java虚拟机必须把一个字符串对象的引用,放到constant pool entry 中。每个java虚拟机维护着一张列表,里面有所有程序被"interned"的字符串对象的引用。查看constPoolOop.cpp文件oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) {  oop entry = *(this_oop->obj_at_addr(which));  if (entry->is_symbol()) {    ObjectLocker ol(this_oop, THREAD);    if (this_oop->tag_at(which).is_unresolved_string()) {      // Intern string      symbolOop sym = this_oop->unresolved_string_at(which);      entry = StringTable::intern(sym, CHECK_(constantPoolOop(NULL)));      this_oop->string_at_put(which, entry);    } else {      // Another thread beat us and interned string, read string from constant pool      entry = this_oop->resolved_string_at(which);    }  }  assert(java_lang_String::is_instance(entry), "must be string");  return entry;}注意有特定字符序列的字符串只会出现一次。如果存在这个Unicode字符序列的字符串,直接返回这个字符串的引用,否则创建新的字符串对象。查看symbolTable.cpp文件oop StringTable::intern(Handle string_or_null, jchar* name,                        int len, TRAPS) {  unsigned int hashValue = hash_string(name, len);  int index = the_table()->hash_to_index(hashValue);  oop string = the_table()->lookup(index, name, len, hashValue);   // Found  if (string != NULL) return string;    // Otherwise, add to symbol to table  return the_table()->basic_add(index, string_or_null, name, len,                                hashValue, CHECK_0);  }the_table()的定义,SymbolTable* SymbolTable::_the_table = NULL;使用string类的intern()方法,来intern一个字符串,如果具有相同字符序列的字符串被intern过,那末intern()方法直接返回被interned字符串对象的引用。这样的代码  public static final String a="123";    public static final String b="123"; System.out.println(a==b); 返回也是true,如果一个程序多个类使用相同的字符串,这些类的方法使用ldc或者ldc_w把内容为"123"的string对象的引用压入栈。也就是说java虚拟机把所有具有相同字符顺序的字符串处理为同一个java对象。对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。 从String源码得知这是一个native方法。查看jdk代码JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str))  JVMWrapper("JVM_InternString");  JvmtiVMObjectAllocEventCollector oam;  if (str == NULL) return NULL;  oop string = JNIHandles::resolve_non_null(str);  oop result = StringTable::intern(string, CHECK_0);  return (jstring) JNIHandles::make_local(env, result);JVM_END也调用了StringTable::intern。 本文参考了小钢翻译深入java虚拟机,又给他捐款了,不知道他包养超女MM的钱够了没有。


阅读全文(6422) | 回复(2) | 编辑 | 精华
 


回复:深入JVM(一):从"abc"=="abc"看java的连接过程
原创空间,  软件技术,  电脑与网络

wueddie(游客)发表评论于2007/9/19 21:34:12

佩服得很。java 和 CPP 同时精通。


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:深入JVM(一):从"abc"=="abc"看java的连接过程
原创空间,  软件技术,  电脑与网络

nurhachi(游客)发表评论于2007/4/25 17:38:57

谢谢,看明白了 C++的代码没读懂

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


» 1 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.250 second(s), page refreshed 144755579 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号